【发布时间】:2020-01-15 02:29:19
【问题描述】:
我目前正在尝试在树视图中进行拖放操作(使用数据绑定和 HierarchicalDataTemplate),并让拖动工作正常进行,但在尝试使拖放工作时遇到问题,因为我需要获取数据项被丢弃并将其添加到其子节点的项目集合中。
//treeitem is the name of my item data class
private void TreeViewItem_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("DragableTreeViewItem"))
{
//the data of the treeitem i need to duplicate, provided by the drag operation
TreeItem data = e.Data.GetData("DragableTreeViewItem") as TreeItem;
TreeViewItem tvi = sender as TreeViewItem;
//here im getting the treeviewitem, but i need the treeitem
}
}
关于如何解决这个问题,我最好的想法是在树的初始化/加载时将 treeitem 分配为 treeviewitem 的标记,为此我需要获取该项目的 itemcontainer,我已经有一个工作函数来获取我在启动 DoDrag() 时使用的函数
//returns the item container of the parent of the TreeItem given
private TreeViewItem GetParentContainerFromItem(TreeItem ti)
{
List<TreeItem> GetOrderedParents(TreeItem item)
{
TreeItem currentParent = item;
List<TreeItem> items = new List<TreeItem>();
int i = 0;
do
{
if (currentParent.parentItem != null)
{
items.Insert(0, currentParent);
currentParent = currentParent.parentItem;
}
else
{
items.Insert(0, currentParent);
i++;
return items;
}
} while (i == 0);
return null;
}
//the local tree in a list, ordered from the original item (in this case "ti") at 0, down to the root at the end of the list
List<TreeItem> LocalHierarchy = GetOrderedParents(ti);
if (LocalHierarchy != null)
{
//print out the names of each treeitem in it, in order from the root down
string hierarchyString = "";
foreach (TreeItem t in LocalHierarchy)
{
if (hierarchyString == "")
{
hierarchyString = t.Title;
}
else
{
hierarchyString = (hierarchyString + ", " + t.Title);
}
}
System.Console.WriteLine(hierarchyString);
TreeViewItem localCurrentParent = null;
TreeViewItem finalContainer = null;
//walk down the tree in order to get the container of the parent
foreach (TreeItem t in LocalHierarchy)
{
//if the parent of the item given is a root node, meaning we can return its container
if (LocalHierarchy.IndexOf(t) == 0 && (LocalHierarchy.IndexOf(t) == (LocalHierarchy.Count - 2)))
{
finalContainer = treeView.ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
break;
}
else
//if we're at a root node
if (LocalHierarchy.IndexOf(t) == 0)
{
localCurrentParent = treeView.ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
}
else
//if we're at the 2nd to last, AKA the parent of the item given
if (LocalHierarchy.IndexOf(t) == (LocalHierarchy.Count - 2))
{
finalContainer = localCurrentParent.ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
break;
}
else
{
localCurrentParent = localCurrentParent.ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
}
}
if (finalContainer == null)
{
System.Console.WriteLine("Final container is null");
}
return finalContainer;
}
else
{
System.Console.WriteLine("ERROR: LocalHierarchy is null");
return null;
}
}
这似乎在用于启动 DoDrag() 时完美运行
private void DoDrag()
{
if(selectedItem != null)
{
TreeItem t = selectedItem;
TreeViewItem tvi = null;
if (t.parentItem == null)
{
//it has no parent, and is a root node
tvi = treeView.ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
}
else
{
//it has a parent, and i can get the container for the parent
tvi = GetParentContainerFromItem(t).ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
}
DragDrop.DoDragDrop(tvi, new DataObject("DragableTreeViewItem", t, true), DragDropEffects.Copy);
dragNeeded = false;
}
else if(selectedItem == null)
{
Console.WriteLine("Selected item was null; cant drag");
}
}
但是当我尝试在我的函数中使用它来分配容器标签时,它说 Container 为 null 并且 GetParentContainerFromItem 返回 null,但我的函数没有记录它返回 null
private void AssignContainerTag(TreeItem t)
{
TreeViewItem Container = null;
if (t.parentItem == null)
{
//its a root node
Container = treeView.ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
Container.Tag = t;
}
else
{
//it is not a root node
Container = GetParentContainerFromItem(t).ItemContainerGenerator.ContainerFromItem(t) as TreeViewItem;
Container.Tag = t;
}
}
我已经花了好几天的时间来思考为什么这似乎不起作用,所以如果有人可以给我一些关于我做错了什么的指示或其他方式我可以从它的容器中获取该项目,这将是一个救命稻草。如果写得不好,也请原谅,我筋疲力尽,要睡觉了。
【问题讨论】:
-
我不打算提供这个作为答案,因为它大约是 5 年前在 Xaml 变体 Silverlight 中。但是我在尝试在两个控件之间拖动时遇到了类似的障碍;我发现在放置时,没有办法辨别(对象的文本除外)究竟被删除了,就好像你在删除时得到了一个新的空白副本。 Uggg,我不记得确切的解决方案,或者我是否不得不放弃它......但你可能需要做更多的挖掘。
标签: c# wpf data-binding