Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将XmlElement从一个列表框拖动到另一个空的Xml绑定列表框_C#_Xml_Wpf_Listbox_Xmldocument - Fatal编程技术网

C# 将XmlElement从一个列表框拖动到另一个空的Xml绑定列表框

C# 将XmlElement从一个列表框拖动到另一个空的Xml绑定列表框,c#,xml,wpf,listbox,xmldocument,C#,Xml,Wpf,Listbox,Xmldocument,我有两个列表框,它们都绑定到两个不同的XML文件。 其目的是将XmlElements从一个文件拖到另一个文件(ListBox)中 当我从一个填充的列表框拖动到另一个填充的列表框时,目标列表框中的代码相当简单。 但是当目标ListBox为空时,很难获取任何XmlElements,因为ListBox不包含任何项 由于未填充目标,代码将在以下位置失败: XmlElement targetXmlElement=(XmlElement)parent.Items.GetItemAt(0) 所以问题是: 如何

我有两个列表框,它们都绑定到两个不同的XML文件。 其目的是将XmlElements从一个文件拖到另一个文件(ListBox)中

当我从一个填充的列表框拖动到另一个填充的列表框时,目标列表框中的代码相当简单。 但是当目标ListBox为空时,很难获取任何XmlElements,因为ListBox不包含任何项

由于未填充目标,代码将在以下位置失败:

XmlElement targetXmlElement=(XmlElement)parent.Items.GetItemAt(0)

所以问题是: 如何从ListBox目标获取XmlDataProvider或XmlDocument:
ListBox父项=(ListBox)发送方

另一个问题是,目标列表框应该包含子节点的列表,即我们所拖动元素的目标。 如何访问父元素

ListBox dragSource = null;
    private void FoodListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        ListBox parent = (ListBox)sender;
        dragSource = parent;
        object data = GetDataFromListBox(dragSource, e.GetPosition(parent));

        if (data != null)
        {
            DragDrop.DoDragDrop(parent, data, DragDropEffects.Copy);
        }
    }

    #region GetDataFromListBox(Listbox, Point)
        private static object GetDataFromListBox(ListBox source, Point point)
        {
            UIElement element = source.InputHitTest(point) as UIElement;
            if(element != null)
            {
                object data = DependencyProperty.UnsetValue;
                while(data == DependencyProperty.UnsetValue)
                {
                    data = source.ItemContainerGenerator.ItemFromContainer(element);
                    if (data == DependencyProperty.UnsetValue)
                    {
                        element = VisualTreeHelper.GetParent(element) as UIElement;   
                    }
                    if (element == source)
                    {
                        return null;
                    }
                }       
                if(data != DependencyProperty.UnsetValue)
                {
                    return data;
                }         
            }

            return null;
        }
    #endregion


    //This listbox is bound to Dataprovider2, Objects dragged into will access the XML target 
    private void ListBox_Drop(object sender, DragEventArgs e)
    {
        ListBox parent = (ListBox)sender;

        //Get access to the element from the source XML
        XmlElement sourceXmlElement = (XmlElement)e.Data.GetData(typeof(XmlElement));

        //Get the position of the parent to any Element in the the target list (e.g the zero element)
        XmlElement targetXmlElement = (XmlElement)parent.Items.GetItemAt(0);

        AppendXmlNode(sourceXmlElement, targetXmlElement);
    }

在WPF中,您不是直接绑定到集合,而是绑定到该集合的

所有集合都有默认的CollectionView。WPF总是绑定到 视图而不是集合。如果直接绑定到集合, WPF实际上绑定到该集合的默认视图。这 默认视图由集合的所有绑定共享,这会导致 所有直接绑定到集合以共享排序、筛选、, 组和一个默认视图的当前项特征

您可以从绑定源中提取
XmlDocument
,而不是提取过滤后的视图

private void targetListBox_Drop(object sender, DragEventArgs e)
{
    ListBox parent = (ListBox)sender;

    //Get access to the element from the source XML
    XmlElement sourceXmlElement = (XmlElement)e.Data.GetData(typeof(XmlElement));

    //Get access to the document from the target XML
    BindingExpression bindingExpression = 
        parent.GetBindingExpression(ListBox.ItemsSourceProperty);
    Binding parentBinding = bindingExpression.ParentBinding;
    XmlDataProvider source = (XmlDataProvider)parentBinding.Source;
    XmlDocument targetXmldocument = source.Document;

    AppendXmlNode(sourceXmlElement, targetXmldocument);
}
一旦你掌握了文档,修改就轻而易举了

private static void AppendXmlNode(XmlElement element, XmlDocument doc)
{
    //Get access to the root node to append child
    XmlNode root = doc.SelectSingleNode("/recipelist/recipe[contains(.,'name')]/foodlist");
    //Detach element from source XmlDocument
    XmlNode clone = doc.ImportNode(element, true);
    root.AppendChild(clone);
}

谢谢你的回答,宝贝

代码段确实将
源返回为null,尽管:

BindingExpression bindingExpression = parent.GetBindingExpression(ListBox.ItemsSourceProperty);
Binding parentBinding = bindingExpression.ParentBinding;
XmlDataProvider source = (XmlDataProvider)parentBinding.Source;
但过了一会儿,我意识到
对象发送者实际上包含了一个DataContext

以下代码解决了我的问题:

    private void ListBox_Drop(object sender, DragEventArgs e)
    {
        ListBox parent = (ListBox)sender;

        //Get access to the element from the source XML
        XmlElement sourceXmlElement = (XmlElement)e.Data.GetData(typeof(XmlElement));

        XmlDataProvider l_context = (XmlDataProvider)parent.DataContext;
        XmlDocument l_XmlDoc = l_context.Document;
        string l_Xpath = l_context.XPath;
        XmlNode l_node = l_XmlDoc.SelectSingleNode(l_Xpath.Replace("/foodlist/foodtype",""));
        XmlElement targetXmlElement = (XmlElement)l_node.SelectSingleNode("foodlist");

        AppendXmlNode(sourceXmlElement, targetXmlElement);
    }

    private void AppendXmlNode(XmlElement source, XmlElement target)
    {
        XmlElement l_source = source;
        XmlElement l_target = target;

        //Append first the Parent 
        XmlNode l_nodeToCopy = l_target.OwnerDocument.ImportNode(l_source, true);
        l_target.AppendChild(l_nodeToCopy);

        XmlDocument l_doc = l_target.OwnerDocument;
        Save(l_doc);
    }

listbox目标使用Xpath=“/recipelist/recipe[contains(,'name')]/foodlist/foodtype”进行过滤,这意味着foodlist为空,Xpath不返回任何内容。我的代码段使用XmlDataProvider作为资源(ref)。再说一遍,剥猫皮的方法不止一种。