UWP 焦点控制
UWP focus control
我在通用 windows 10 应用程序中有带文本框的 ListView。我想编写代码:用户在 Listiew 中编辑任何 TextBox 并单击回车键,我想将焦点移动到 ListView 中的下一个 TextBox(我想采取与用户单击 Tab 键时发生的相同操作)。
我的问题是:如何以编程方式将焦点移动到下一个 listView 元素
假设我们有一个像这样的模型对象:
public sealed class Item
{
public string Value { get; set; }
}
让我们用他们的字符串填充 ListView
:
<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>
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);
}
棘手的部分是从逻辑列表(由 Items
组成)到可视列表(ListViewItem
s 包装 TextBox
es)的映射。
我在通用 windows 10 应用程序中有带文本框的 ListView。我想编写代码:用户在 Listiew 中编辑任何 TextBox 并单击回车键,我想将焦点移动到 ListView 中的下一个 TextBox(我想采取与用户单击 Tab 键时发生的相同操作)。
我的问题是:如何以编程方式将焦点移动到下一个 listView 元素
假设我们有一个像这样的模型对象:
public sealed class Item
{
public string Value { get; set; }
}
让我们用他们的字符串填充 ListView
:
<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>
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);
}
棘手的部分是从逻辑列表(由 Items
组成)到可视列表(ListViewItem
s 包装 TextBox
es)的映射。