简体   繁体   中英

UWP focus control

I have ListView with TextBoxes in universal windows 10 app. I want to write code: where user is editing any TextBox in Listiew and click enter key, I want to move focus to next TextBox in ListView (I want take the same action what happens where user click Tab key).

My question is: How to move focus programatically to the next listView element

Assume we have a model object like so:

public sealed class Item
{
    public string Value { get; set; }
}

Let's fill a ListView with their strings:

<ListView x:Name="listView">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Value}" Loaded="OnTextBoxLoaded" />
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.Items>
        <local:Item Value="One" />
        <local:Item Value="Two" />
        <local:Item Value="Three" />
        <local:Item Value="Four" />
    </ListView.Items>
</ListView>

The code-behind:

public sealed partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void OnTextBoxLoaded(object sender, RoutedEventArgs e)
    {
        TextBox textBox = (TextBox)sender;
        textBox.KeyUp += (o, args) =>
            {
                if (args.Key == VirtualKey.Enter)
                {
                    TextBox originalSource = (TextBox)args.OriginalSource;
                    int index = 0;
                    var items = listView.Items;
                    if (items != null)
                    {
                        foreach (Item item in items)
                        {
                            if (originalSource.DataContext == item)
                            {
                                break;
                            }

                            ++index;
                        }

                        index = (index + 1) % items.Count;
                        ListViewItem container = (ListViewItem)listView.ContainerFromIndex(index);
                        TextBox nextTextBox = FindVisualChild<TextBox>(container);
                        nextTextBox?.Focus(FocusState.Programmatic);
                    }
                }
            };
    }

    private static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
    {
        if (parent != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);
                T candidate = child as T;
                if (candidate != null)
                {
                    return candidate;
                }

                T childOfChild = FindVisualChild<T>(child);
                if (childOfChild != null)
                {
                    return childOfChild;
                }
            }
        }

        return default(T);
    }

The tricky part is the mapping from the logical list (consisting of Items ) to the visual list ( ListViewItem s wrapping TextBox es).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM