wpf - 在作为 ListBoxItem 内容的 UserControl 上的 TextBox 上设置焦点

标签 wpf xaml mvvm focus listboxitem

我有一个 ButtonUserControl将项目添加到 ListBox在那UserControl .我们称该控件为父控件。 ListBoxItem s 包含另一个 UserControl .我们就叫那个 child 吧。该按钮将一个项目添加到 ItemSource的列表框(MVVM 风格)。
我可以毫无问题地将其滚动到 View 中。我可以将焦点设置到 ListBoxItem ,但我想要的是将焦点设置在第一个 TextBox child 的UserControl ListBoxItem 的内容.我似乎无法弄清楚。下面的代码将焦点设置为 ListBoxItem ,而不是 UserControl它的子节点或对其的任何控制。

Private Sub bnAdd(sender As Object, e As RoutedEventArgs)
   VM.AddDetail()
   MyList.ScrollIntoView(MyList.Items(MyList.Items.Count - 1))
   Dim ListBoxItem As ListBoxItem = MyList.ItemContainerGenerator.ContainerFromItem(MyList.SelectedItem)
   ListBoxItem.Focus()
End Sub
我的 child UserControl我在 XAML 中使用了这个:
FocusManager.FocusedElement="{Binding ElementName=txtMyBox}"

最佳答案

有一个相关问题here并且大多数方法使用 Hook 焦点事件来实现焦点更改。我想提出另一种基于遍历可视化树的解决方案。不幸的是,我只能为您提供 C# 代码,但您可以使用该概念将其应用到您的 Visual Basic 代码中。
据我所知,您正在使用代码隐藏将您的项目滚动到 View 中。我会以此为基础。您的列表框有列表框项目,我猜您使用数据模板来显示 UserControl s 作为子项。在这些用户控件中有一个 TextBox您已通过 x:Name 在 XAML 中分配了一个名称或通过 Name 在代码隐藏中属性(property)。现在,您需要一个辅助方法来遍历可视化树并搜索文本框。

private IEnumerable<TextBox> FindTextBox(DependencyObject dependencyObject)
{
   // No other child controls, break
   if (dependencyObject == null)
      yield break;

   // Search children of the current control
   for (var i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
   {
      var child = VisualTreeHelper.GetChild(dependencyObject, i);

      // Check if the current item is a text box
      if (child is TextBox textBox)
         yield return textBox;

      // If we did not find a text box, search the children of this child recursively
      foreach (var childOfChild in FindTextBox(child))
         yield return childOfChild;
   }
}
然后我们添加一个方法,使用 Linq 过滤给定名称的可枚举文本框。
private TextBox FindTextBox(DependencyObject dependencyObject, string name)
{
   // Filter the list of text boxes for the right one with the specified name
   return FindTextBox(dependencyObject).SingleOrDefault(child => child.Name.Equals(name));
}
在您的 bnAdd处理程序你可以带你的ListBoxItem ,搜索文本框子项并将其聚焦。
var textBox = FindTextBox(listBoxItem, "MyTextBox");
textBox.Focus();

关于wpf - 在作为 ListBoxItem 内容的 UserControl 上的 TextBox 上设置焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63120400/

相关文章:

WPF在单击复选框时传递多个参数

c# - 包含两个 Caliburn.Micro View 的对话框 View ?

wpf - 如何对组合框的 Observable 集合进行排序

c# - 为什么我的数据绑定(bind) TabControl 看起来不像我的非数据绑定(bind) TabControl?

c# - 文本框已聚焦,但在我单击之前无法键入 - XAML/C#/WPF

javascript - 空数组绑定(bind)元素在页面加载时消失

c# - 调用 .Show on new Window 时 UI 卡住

wpf - 如何防止任务栏出现在 WPF 非全屏窗口中?

wpf - 鼠标悬停时更改背景颜色

c# - TreeView 上下文菜单在 HierarchicalDataTemplate 中不起作用