对于我正在进行的项目,我需要使用拖放重新排序创建树视图。在搞乱实际项目之前,我在一个单独的项目中将treeview子类化,并为Drop,DragOver,MouseMove和DragLeave事件添加了处理程序,并在必要时实现它们。拖放重新排序适用于副项目,因为我设置了这样,每个TreeViewItem将我感兴趣的项目存储在Header属性中。
以下是一些代码:
void MultiSelectTreeView_Drop(object sender, System.Windows.DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(TreeViewItem)))
{
TreeViewItem sourceItem = (TreeViewItem)e.Data.GetData(typeof(TreeViewItem));
TreeViewItem targetItem = e.Source as TreeViewItem;
dynamic parent;
if (targetItem == null) //not dropped in the treeview
{
_isDragging = false;
return;
}
else if (targetItem.Parent is TreeViewItem) //drag must start from either a treeviewitem...
{
parent = targetItem.Parent as TreeViewItem;
}
else // ... or the root treeview
{
parent = targetItem.Parent as TreeView;
}
//Complete the drag/drop
//must be same parent to successfully drop
if(sourceItem.Parent == targetItem.Parent)
{
var indexOfDropTarget = parent.Items.IndexOf(targetItem);
parent.Items.RemoveAt(parent.Items.IndexOf(sourceItem));
parent.Items.Insert(indexOfDropTarget, sourceItem);
sourceItem.IsSelected = true;
}
}
_isDragging = false;
}
我需要的树视图的规则是,为了重新排序而被删除的项目只能在同一个父项中重新排序。
上面的代码效果很好,假设treeviews子项都是treeview项,每个都包含我感兴趣的数据结构。
当我将新的treeview类移动到更大的项目时,我注意到因为树视图绑定到视图模型中的集合,e.Data不再是树视图项目!它现在是视图模型的数据结构。 e.Source也不再是一个树视图项目,它是整个树视图所以我无法告诉我在哪里“丢弃”该项目。
树视图是根据视图模型中的数据结构自动构建的。每个项目都有一个Children属性,Children属性中的每个项目都可以有自己的子项。我的要求是,可以对子属性中的项目进行重新排序,但不能将子项移动到其父项存储在其中的同一个集合中,也不能移动到其中一个子项集合中。
我的问题是:如何拖动TreeViewItem并删除TreeViewItem?我需要能够看到每个人的父母,并确保他们是一样的。
我是以错误的方式来做这件事的吗?我应该将命令传回视图模型吗?
谢谢!
答案 0 :(得分:1)
我认为您需要找到数据结构的容器。 如果您需要这种方式,我使用此代码完成了此操作:
TreeViewItem container = myTreeViewItem.ItemContainerGenerator.ContainerFromItem(child).As<TreeViewItem>();
你必须在树中迭代才能找到孩子的容器。因为从视图中你没有引用子对象的直接父对象的容器,你必须从root(treeview)迭代地找到它。
答案 1 :(得分:-1)
我最终做的是走在视觉树上。我能够得到事件首次出现的文本块,从那里只是走到树上直到找到合适的树视图。
我正在寻找的项目仍然存储在treeviewitem.header属性中。
如果有其他人遇到同样的问题,this link will teach you everything you need