C# 将XmlElement从一个列表框拖动到另一个空的Xml绑定列表框
我有两个列表框,它们都绑定到两个不同的XML文件。 其目的是将XmlElements从一个文件拖到另一个文件(ListBox)中 当我从一个填充的列表框拖动到另一个填充的列表框时,目标列表框中的代码相当简单。 但是当目标ListBox为空时,很难获取任何XmlElements,因为ListBox不包含任何项 由于未填充目标,代码将在以下位置失败: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) 所以问题是: 如何
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)。再说一遍,剥猫皮的方法不止一种。