使用TabIndex在字段之间“Tabbing”

时间:2014-01-20 08:56:55

标签: c# xaml windows-phone-8

问题

在我使用.NET 4.5的 Windows Phone 8 C#/ XAML应用程序中,我试图通过表单“迭代”。换句话说,当用户按下“Enter”键时,焦点会更改为另一个TextBoxPasswordBox

我的代码现在看起来如何

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...
    }
}    

问题

  1. 如何选择下一个元素来关注TABINDEX ??? 我知道我应该使用LINQ,选择usercontrol中的所有文本框,然后选择带有tabindex索引的文本框。我正在慢慢地自己解决这个问题(并在评论中与人们讨论),但是因为我花了很长时间才写下这个问题:)
  2. *(另外,我也不确定如何命名这个问题,如果您认为自己的名字更适合,请随时重命名)

    基于SACHA答案的解决方案

    LayoutRoot是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();
                }
            }
        }
    

    非常感谢! :)

4 个答案:

答案 0 :(得分:6)

这是一种可能的实施方式。

<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>

下一个代码假设ContentPanel仅包含TextBox。您可以在其中添加更多智能代码......

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();
        }
    }
}

答案 1 :(得分:4)

如果对任何人都有帮助,在8.1中(不知道它是否适用于8)你可以这样做:

private void OnKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key.Equals(Key.Enter))
    {
        FocusManager.TryMoveFocus(FocusNavigationDirection.Next);
    }
}

答案 2 :(得分:1)

您甚至无需命名ContentPanel

private void OnKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key.Equals(Key.Enter))
    {
        var currentBox = (TextBox)sender;
        var container = currentBox.Parent;
        var index = currentBox.TabIndex + 1;
        var nextBox = container.ChildrenOfType<TextBox>().FirstOrDefault(box => box.TabIndex == index);

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

答案 3 :(得分:1)

protected void FocusOnTheNextTabIndex(object sender, FocusEventArgs e)
        {

            int nextIndex = e.VisualElement.TabIndex + 1;
            var element = sender as Element;
            View nextElement = VerifyParent(element, nextIndex);
            if (nextElement != null)
                nextElement.Focus();
        }

 public View VerifyParent(Element element, int index)
        {
            var parent = element.Parent;
            if (parent.GetType() == typeof(StackLayout))
            {
                var stackParent = parent as StackLayout;
                var response = VerifyChildren(stackParent, index);
                if (response != null)
                    return response;
                else
                    return VerifyParent(parent, index);
            }
            return null;
        }

        public View VerifyChildren(StackLayout stackLayout, int index)
        {
            foreach (View view in stackLayout.Children)
            {
                if (view.TabIndex == index)
                    return view;
                else if (view.GetType() == typeof(StackLayout))
                {
                    var stack = view as StackLayout;
                    if (stack.Children.Any())
                    {
                        var response = VerifyChildren(stack, index);
                        if (response != null)
                            return response;
                    }
                }
            }
            return null;
        }