我有一个树视图,我试图实现拖放功能。
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<EventSetter Event="TreeViewItem.PreviewMouseLeftButtonDown" Handler="PreviewMouseLeftButtonDown" />
</Style>
</TreeView.ItemContainerStyle>
然后我在后面的代码中有一个事件来处理点击,然后开始拖动:
void PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (sender is TreeViewItem)
{
//clone the tree item, create an adorner, apply adorner
//doDragDrop
}
}
我的问题是,因为PreviewMouseLftButtonDown是使用隧道策略的路由事件,当在treenode项目上单击鼠标时,我首先获得根节点。我对根节点不感兴趣,只对叶节点感兴趣。我的结构是这样的:
HeaderNodeObject
|_LeafnodeObject
|_LeafNodeOject
所以在我的事件中我基本上不需要做任何事情,只要发送者treeViewItem是HeaderNodeObject就继续。但是我该如何判断它是什么?发件人作为treeViewItem进来,我不知道如何判断它所拥有的对象是什么。
答案 0 :(得分:1)
上述解决方案仅适用于leafs,我必须为TreeView执行此操作,我希望在树中的任何节点上处理PreviewMouseLeftDown事件。我终于通过忽略孩子鼠标悬停的所有节点的事件来解决它。像这样:
var treeViewItem = sender as TreeViewItem;
if (treeViewItem.Items.OfType<TreeViewItem>().All(item => !item.IsMouseOver))
{
//do my stuff
}
一种hackish解决方案,但我找不到更好的,至少它完成了工作......
答案 1 :(得分:1)
您应该可以使用e.Source as TreeViewItem
来检索已点击的项目。您可以针对sender
进行检查,以确认您只在到达来源时处理该事件。
这会导致仅针对所点击的项目处理事件:
void PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.Source is TreeViewItem item && sender == item)
/* do something */;
}
但是,请注意,直接使用事件意味着如果项目的任何部分收到鼠标按下事件(包括扩展按钮),您将收到该事件。因此,请注意 * not * 设置e.Handled = true
,以免您阻止用户切换扩展等。
答案 2 :(得分:0)
我只是通过检查发件人的itemsource是否为空来简单地解决了这个问题。如果它的null表示它的叶节点:
if (sender is TreeViewItem)
{
Item = sender as TreeViewItem;
//make sure we have a leaf node, if we dont just move on.
if (Item.ItemsSource == null)
{
//do my stuff
}
}
答案 3 :(得分:0)
不会将此称为重复答案,但只会提及ØysteinKolsrud的答案是正确的,因为这可能没有数据绑定。我没有足够的声誉,否则我只会评论和投票,但“用户”的答案只适用于树上的叶子,而Øystein的答案适用于树上的所有节点,包括所有叶子节点。 / p>
我的案例涉及通过一个相当浅(但人口密集)的递归填充的“工作项”树。我使用TreeView来显示工作流层次结构,其中所选节点将引发从TreeViewItem的标头捕获Work ID文本的事件,因此我可以以有意义的方式使用该WorkID。当我希望这不仅仅是根或只是第一级孩子(留下根)时,Øystein的回答就是我必须走的路。绝对是hackish,但绝对有效。
我以前的所有代码(除了他的条件检查)之前都有。我所要做的只是包括他的支票,一切都按照我最初的预期进行。
只是想分享这个工作的真实例子并验证他的工作。这种情况就像一个魅力,拯救了我的屁股。再次感谢,ØysteinKolsrud!!
private void TreeItem_Selected(object sender, RoutedEventArgs e)
{
TreeViewItem workItem = sender as TreeViewItem;
if(workItem.Items.OfType<TreeViewItem>().All(item => !item.IsMouseOver))
{
string workItemHeader = workItem.Header.ToString();
string stopAt = "-";
currentWorkIDToEdit = workItemHeader.Substring(0, workItemHeader.IndexOf(stopAt));
workItemToEdit.Content = "Work Item To Edit: " + currentWorkIDToEdit + " ";
}
}