如何在Drop事件中访问Source的Parent?

时间:2018-04-18 14:28:57

标签: c# wpf drag-and-drop treeview

我正在尝试为TreeView中的值处理一些拖放功能。 我专门针对Drop方法。我希望能够访问被拖动元素的Parent对象。

TreeView.SelectedItem

是TreeView的属性,我怀疑我需要它。但是,此属性的类型为string,因此访问Parent对象是一个挑战。

我尝试使用

VisualTreeHelper.GetParent(DependencyObject)

方法但似乎不存在从字符串到DependencyObject的转换,反之亦然。

我能够访问目标的ParentControl,但不能访问源代码,我无法理解原因。

这是我的Drop Method,以及MouseMove。任何帮助将不胜感激。

 private void TreeViewItem_Drop(object sender, DragEventArgs e)
    {
        if (sender is TreeViewItem target)
        {
            string source = e.Data.GetData(typeof(string)) as string;
            string dropTarget = target.DataContext as string;
            var parentControl = VisualTreeHelper.GetParent((TreeViewItem)(sender));
            var parentElement = ((VirtualizingStackPanel)(parentControl)).DataContext;

            if (parentElement is GroupDecision decision)
            {
                if (decision.Decisions.Contains(source) && (decision.Decisions.Contains(dropTarget)))
                {
                    int sourceIndex = decision.Decisions.IndexOf(source);
                    int targetIndex = decision.Decisions.IndexOf(dropTarget);
                    SwapElements(sourceIndex, targetIndex, decision.Decisions);
                }
                else
                {
                    if (!decision.Decisions.Contains(source))
                    {
                        decision.Decisions.Add(source);
                        // Remove from old

                    }
                }
            }
        }



 private void TreeViewItem_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            if (TreeView.SelectedItem != null)
            {
                DragDrop.DoDragDrop(this, TreeView.SelectedItem, DragDropEffects.Move);
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

你的dodragdrop中的treeview.selecteditem会在你执行你的e.Data.GetData时在你的数据中结束。因为你将它转换为字符串,它只是一个在内存中浮动的字符串。漂浮在不在视觉树上的海洋上。它没有父控件,因为它是一个字符串。 发件人是你放弃它的任何控件,所以这不是你拖的东西。这就是你要拖的东西。

但是......你传递的数据可以是你提供的任何数据 这可以是一个简单的字符串,也可以是一个复杂的业务对象,上面有很多属性 无论你什么时候放弃,最好藏在那里的数据中 在这里答案: WPF drag and drop and data types 这是一个视图模型。

我并不真正关注你想要的东西,而不是

DragDrop.DoDragDrop(this, TreeView.SelectedItem, DragDropEffects.Move);

你应该把所需的东西作为第二个参数。

DragDrop.DoDragDrop(this, AmoreComplexObjectWithMoreData, DragDropEffects.Move);

定义一个具有匹配任何所需属性的类。新建它并在开始拖动时设置它们。当你放弃时,你拥有了你需要的一切。将拖动数据转换回所述类。

答案 1 :(得分:0)

string没有视觉祖先。也许您想将所选项目的TreeViewItem容器传递给DoDragDrop方法?:

private void TreeViewItem_MouseMove(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        if (TreeView.SelectedItem != null)
        {
            DragDrop.DoDragDrop(this,
                TreeView.ItemContainerGenerator.ContainerFromItem(TreeView.SelectedItem) as TreeViewItem,
                DragDropEffects.Move);
        }
    }
}

然后,您可以在Drop事件处理程序中获取对可视容器的引用,并根据需要遍历可视树:

TreeViewItem source = e.Data.GetData(typeof(TreeViewItem)) as TreeViewItem;
string sourceObject = source.DataContext as string;
//...