最简单的方法是使用冒泡事件MouseRightButtonDown而不是隧道事件PreviewMouseRightButtonDown。您可以将路由事件标记为已处理,方法是将EventArgs的Handled属性设置为true,这将停止调用进一步的事件处理程序。这样,只有最深的TreeViewItem才会收到该事件。
如果您不能使用预览事件,另一种方法是使用EventArgs中的OriginalSource属性来查找实际单击的UI元素。这可能是您的RichTextBox,因此您将需要使用一种方法来查找TreeViewItem类型的可视祖先。有一个在http://www.wpftutorial.net/LogicalAndVisualTree.html一个方法来获得一个给定类型的祖先的例子:
public static class VisualTreeHelperExtensions
{
public static T FindAncestor<T>(DependencyObject dependencyObject)
where T : class
{
DependencyObject target = dependencyObject;
do
{
target = VisualTreeHelper.GetParent(target);
}
while (target != null && !(target is T));
return target as T;
}
}
所以,你可以调用((DependencyObject)e.OriginalSource).FindAncestor<TreeViewItem>()
找到被点击的树型视图。如果你这样做,你应该将事件处理程序附加到TreeView本身而不是TreeViewItems。这将在任何TreeViewItem中捕获点击,因为它们都在树中,但它只会被称为一次。
编辑:正如您指出,该方法不一样,如果目标是FrameworkContentElement上,因为它不是一个Visual工作。你可以做这样的事情,而不是:
public static class VisualTreeHelperExtensions
{
public static T FindAncestor<T>(object dependencyObject)
where T : DependencyObject
{
var target = (DependencyObject)dependencyObject;
do
{
var visualParent = target is Visual ? VisualTreeHelper.GetParent(target) : null;
if (visualParent != null)
{
target = visualParent;
}
else
{
var logicalParent = LogicalTreeHelper.GetParent(target);
if (logicalParent != null)
{
target = logicalParent;
}
else
{
return null;
}
}
}
while (!(target is T));
return (T)target;
}
}
那么你应该能够做VisualTreeHelperExtensions.FindAncestor<TreeViewItem>(e.OriginalSource)
从OriginalSource得到树型视图。
感谢您的想法,但在我的情况下,我不得不使用预览事件,因为树视图项目具有模板的richtextbox,并且它不会触发TreeViewItem的冒泡事件。 e.OriginalSource不是richtextbox它是richtextbox中的flowdocument或Run或其他元素(将根据我右键单击的位置进行更改) – Niruka 2010-07-21 14:00:52
@Niruka:对不起,我包含的方法没有处理FrameworkContentElement象Run的对象。看到我更新的答案。 – Quartermeister 2010-07-21 15:40:06
非常感谢。第二种方法奏效。我做了一个非常小的修改。该行目标=((FrameworkElement)目标).Parent;已更改为 target = VisualTreeHelper.GetParent(target); 看起来像,在回顾TreeViewItem的方式,属性((FrameworkElement)目标).Parent已经返回null,当我们击中一个Border元素,但VisualTreeHelper.GetParent(目标);将返回正确的父母。这应该有一个合理的解释,但我对WPF太新了。再次感谢。顺便说一句,我不知道如何设置这个问题的状态作为回答抱歉。 – Niruka 2010-07-22 09:10:49