Search code examples
c#xamlwindows-phone-8

"Tabbing" between fields using TabIndex


PROBLEM

In my Windows Phone 8 C#/XAML Application using .NET 4.5 I'm trying to "iterate" through form. In other words, when the user presses "Enter" key, the focus changes to another TextBox or PasswordBox.

HOW MY CODE LOOKS LIKE NOW

XAML:

<TextBox TabIndex="0" KeyDown="TextBox_KeyDown"/>
<TextBox TabIndex="1" KeyDown="TextBox_KeyDown"/>
<TextBox TabIndex="2" KeyDown="TextBox_KeyDown"/>
<TextBox TabIndex="3" KeyDown="TextBox_KeyDown"/>
<TextBox TabIndex="4" KeyDown="TextBox_KeyDown"/>
....

C# CodeBehind:

using System.Windows.Input;

private void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
    if (e.Key.Equals(Key.Enter))
    {
        int index = ((TextBox)sender).TabIndex + 1;
        //and here is what I've been missing
        //basically the code to select next tabindex
        //and set focus on it using Focus() method...
    }
}    

QUESTION

  1. HOW TO SELECT NEXT ELEMENT TO FOCUS ON BY TABINDEX??? I know I should probably use LINQ, to select all textboxes in the usercontrol and then select the one with tabindex index. I'm slowly figuring it on my own (and also by discussing it with people in the comments), but as it's taking me a long time I wrote the question :)

*(also, I was not sure how to name the question, feel free to rename it if you think your name fits it better)

SOLUTION BASED ON SACHA's ANSWER

LayoutRoot is the main grid of usercontrol

    private void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key.Equals(Key.Enter))
        {
            int index = ((TextBox)sender).TabIndex + 1;
            var nextBox = LayoutRoot.Children.OfType<TextBox>().FirstOrDefault((x) => { return x.TabIndex == index; });

            if (nextBox != null)
            {
                nextBox.Focus();
            }
        }
    }

Thanks a lot! :)


Solution

  • This is a possible implementation.

    <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"
                >
        <TextBox TabIndex="0" KeyDown="OnKeyDown"/>
        <TextBox TabIndex="1" KeyDown="OnKeyDown"/>
        <TextBox TabIndex="2" KeyDown="OnKeyDown"/>
        <TextBox TabIndex="3" KeyDown="OnKeyDown"/>
        <TextBox TabIndex="4" KeyDown="OnKeyDown"/>
    </StackPanel>
    

    This next code assume that the ContentPanel contains only TextBox. It's up to you to add more smart code in it...

    private void OnKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key.Equals(Key.Enter))
        {
            var txtBox = sender as TextBox;
            var index = txtBox.TabIndex;
    
            var nextTextBox = ContentPanel.Children.Cast<TextBox>().FirstOrDefault(t => t.TabIndex == index + 1);
    
            if (nextTextBox != null)
            {
                nextTextBox.Focus();
            }
        }
    }