在一个事件中,我想将焦点放在 ListViewItem 模板中的特定文本框上。 XAML 如下所示:
<ListView x:Name="myList" ItemsSource="{Binding SomeList}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<!-- Focus this! -->
<TextBox x:Name="myBox"/>
我在后面的代码中尝试了以下内容:
(myList.FindName("myBox") as TextBox).Focus();
但我似乎误解了
FindName()
docs,因为它返回 null
.还有
ListView.Items
没有帮助,因为(当然)包含我绑定(bind)的业务对象并且没有 ListViewItems。myList.ItemContainerGenerator.ContainerFromItem(item)
也没有,它也返回 null。
最佳答案
正如其他人所指出的,通过在 ListView 上调用 FindName 无法找到 myBox 文本框。但是,您可以获取当前选中的 ListViewItem,并使用 VisualTreeHelper 类从 ListViewItem 中获取 TextBox。这样做看起来像这样:
private void myList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (myList.SelectedItem != null)
{
object o = myList.SelectedItem;
ListViewItem lvi = (ListViewItem)myList.ItemContainerGenerator.ContainerFromItem(o);
TextBox tb = FindByName("myBox", lvi) as TextBox;
if (tb != null)
tb.Dispatcher.BeginInvoke(new Func<bool>(tb.Focus));
}
}
private FrameworkElement FindByName(string name, FrameworkElement root)
{
Stack<FrameworkElement> tree = new Stack<FrameworkElement>();
tree.Push(root);
while (tree.Count > 0)
{
FrameworkElement current = tree.Pop();
if (current.Name == name)
return current;
int count = VisualTreeHelper.GetChildrenCount(current);
for (int i = 0; i < count; ++i)
{
DependencyObject child = VisualTreeHelper.GetChild(current, i);
if (child is FrameworkElement)
tree.Push((FrameworkElement)child);
}
}
return null;
}
关于wpf - 如何访问 WPF ListView 的 ListViewItems?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/92328/