带有 TextBox 子项的 TreeView SelectedItem 行为
Posted
技术标签:
【中文标题】带有 TextBox 子项的 TreeView SelectedItem 行为【英文标题】:TreeView SelectedItem behavior with TextBox children 【发布时间】:2012-04-09 02:20:51 【问题描述】:当 TreeViewItem 是像 Textbox 这样的输入控件时,不会发生 TreeView 的 SelectedItemChanged 事件和 SelectedItem 属性。下面的示例代码通过在 TreeView SelectedItemChanged 事件中放置断点来说明问题。 This breakpoint will fire when "String Header" is selected, but not "Textbox Header".
我假设 Textbox 或 RichTextbox(我的真实应用程序)正在吃一些重要的冒泡事件。如何让 TreeView SelectedItem 对 TextBox 的行为与对 Label 等控件的行为一样?
注意:如果我能解决这个问题,我将需要双向绑定到 SelectedItem,因为我正在使用 MVVM 和 MEF。 SelectedItem 是只读的,这是我打算用 (http://silverscratch.blogspot.com/2010/11/two-way-binding-on-treeviewselecteditem.html) 解决的问题。我认为这个相关链接可能会对某人有所帮助。
XAML:
<TreeView SelectedItemChanged="TreeView_SelectedItemChanged">
<TreeViewItem>
<TreeViewItem.Header>
<TextBox>
Textbox Header
</TextBox>
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem>
<TreeViewItem.Header>
String Header
</TreeViewItem.Header>
</TreeViewItem>
</TreeView>
代码背后:
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
// Breakpoint will fire when "String Header" Selected
// !!! Breakpoint does not fire when Textbox Selected
var newValue = e.NewValue;
var oldValue = e.OldValue;
谢谢,
【问题讨论】:
【参考方案1】:您应该在您的TreeView
上捕获GotFocus
事件:
<TreeView SelectedItemChanged="TreeView_SelectedItemChanged"
GotFocus="UIElement_OnGotFocus">
<TreeViewItem>
<TreeViewItem.Header>
<TextBox>Textbox Header</TextBox>
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem>
<TreeViewItem.Header>String Header</TreeViewItem.Header>
</TreeViewItem>
</TreeView>
private void UIElement_OnGotFocus(object sender, RoutedEventArgs e)
TreeViewItem item = UIHelpers.TryFindParent<TreeViewItem>
((DependencyObject) e.OriginalSource);
if (item != null)
item.IsSelected = true;
TryFindParent
的实现你可以在这里找到:https://***.com/a/4838168/1088908
【讨论】:
恐怕我过度简化了我的问题。我的 TreeView 的文本框 TreeViewItems 实际来自 MEF 的第 3 方程序集。长话短说,我必须处理 TreeView 上的事件。但是,您认为我可以/应该在 TreeView 级别处理这个冒泡的 GotFocus 事件吗? 当然,即使您将 GotFocus="UIElement_OnGotFocus" 移动到 TreeView,它也能正常工作。但不要忘记在处理程序中添加此检查: item != null (我已经更新了答案) 太棒了!如果可以的话,我必须结束问题。 1)出于理解目的,您知道为什么 SelectedItemChanged 会自动为 TreeViewItems 内容(如 Label 而不是 Textbox)工作 - 什么是缺席冒泡事件? 2) 在您链接的 GetParentObject 方法中,最后的手段是使用 VisualTreeHelper。为什么仅使用 VisualTreeHelper 查找父级是不够的? 1.我不确切知道,但在键盘焦点上感觉到这个问题。您知道 WPF 有两个焦点:“键盘”和“逻辑”,它们之间没有直接的依赖关系。如果使用 TextBox,它会捕获“键盘”焦点而不是“逻辑”... 2. 我很久以前就发现了这种方法,许多 WPF 驱动的人经常在示例中使用它。我在我的项目中的很多地方都使用了它,并且效果很好:) 这是具有良好 cmets 的版本sites.google.com/site/bobstechwiki/home/wpf-ji-shu-1/… 我尝试了这种方法,当我单击 TextBox 时它会选择 TreeViewItem,但它不会将光标放在 TextBox 中,直到我再次单击 TextBox(同时选择 TreeViewItem)。有没有办法选择 TreeViewItem 并在第一次单击时仍保持编辑模式处于活动状态?以上是关于带有 TextBox 子项的 TreeView SelectedItem 行为的主要内容,如果未能解决你的问题,请参考以下文章