最簡單的方法是使用冒泡事件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