C# 在XAML中数据绑定到XML:如何附加新的XmlNode?
到目前为止,我所发现的关于数据绑定到XML的一切似乎都只是绑定到一个固定的XML结构。如果有人能给我指点方向,那就太好了。到目前为止,我尝试的每件事都显得很尴尬 这就是我想做的: 将复选框的选中状态绑定到XML中的节点。 因此,将检查XML中是否存在此特定节点,如果不存在则取消选中 对于单向绑定,这并不难(使用返回“value!=null”的转换器绑定到节点) 现在,我还希望看到这个特定节点添加到基础XmlDocument中或从中删除 有没有一个简单的方法可以做到这一点 到目前为止,我尝试的是单向绑定并添加CheckedChanged Eventhandler来处理添加/删除部分。这方面的代码很糟糕,它不会更新到这个XmlDataProvider的绑定 作为一个一般且简化的问题:在WPF中将新的XmlNodes添加到绑定的Xml结构中的好方法是什么C# 在XAML中数据绑定到XML:如何附加新的XmlNode?,c#,wpf,xml,data-binding,xaml,C#,Wpf,Xml,Data Binding,Xaml,到目前为止,我所发现的关于数据绑定到XML的一切似乎都只是绑定到一个固定的XML结构。如果有人能给我指点方向,那就太好了。到目前为止,我尝试的每件事都显得很尴尬 这就是我想做的: 将复选框的选中状态绑定到XML中的节点。 因此,将检查XML中是否存在此特定节点,如果不存在则取消选中 对于单向绑定,这并不难(使用返回“value!=null”的转换器绑定到节点) 现在,我还希望看到这个特定节点添加到基础XmlDocument中或从中删除 有没有一个简单的方法可以做到这一点 到目前为止,我尝试的是单
感谢您的帮助据我所知,XmlDataProvider不提供操作节点结构的功能,只提供操作值的功能。因此,如果您想要操纵节点,则需要针对通过提供的XmlDocument实例编写代码。据我所知,XmlDataProvider不提供操纵节点结构的功能,只提供操纵值的功能。因此,如果您想要操纵节点,您需要编写代码,以针对通过提供的XmlDocument实例进行操作。如果有人感兴趣,这就是我想到的: XAML:
<Window.Resources>
<local:NodeAvailableConverter x:Key="MyConverter"/>
<XmlDataProvider x:Key="xmlsource">
<x:XData>
<main xmlns="">
<sub/>
</main>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<DockPanel DataContext="{Binding Source={StaticResource xmlsource}}">
<CheckBox Content="CheckBox1" DockPanel.Dock="Top">
<i:Interaction.Behaviors>
<local:MyBehavior SourceProv="{StaticResource xmlsource}" XPath="main">
<local:Node Name="sub">
<local:Attribute Name="yeah" Value="added1"/>
</local:Node>
</local:MyBehavior>
</i:Interaction.Behaviors>
</CheckBox>
<CheckBox Content="CheckBox2" DockPanel.Dock="Top">
<i:Interaction.Behaviors>
<local:MyBehavior SourceProv="{StaticResource xmlsource}" XPath="main">
<local:Node Name="sub">
<local:Attribute Name="yeah" Value="added2"/>
</local:Node>
</local:MyBehavior>
</i:Interaction.Behaviors>
</CheckBox>
<Label Content="{Binding OuterXml}" />
</DockPanel>
行为:
[ContentProperty("CustomNode")]
public class MyBehavior : Behavior<CheckBox>
{
protected override void OnAttached()
{
base.OnAttached();
binding = new Binding();
binding.XPath = XPath + "/" + CustomNode.Name;
binding.Mode = BindingMode.OneWay;
binding.Converter = NodeAvailableConverter.Instance;
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty, binding);
AssociatedObject.Click += new RoutedEventHandler(AssociatedObject_Click);
SourceProv.Refresh();
}
void AssociatedObject_Click(object sender, RoutedEventArgs e)
{
var parent = SourceProv.Document.SelectSingleNode(XPath);
if(AssociatedObject.IsChecked==true)
{
var newelement = SourceProv.Document.CreateElement(CustomNode.Name);
foreach (var at in CustomNode.Attributes)
newelement.SetAttribute(at.Name, at.Value);
parent.AppendChild(newelement);
}
else if (AssociatedObject.IsChecked == false)
parent.RemoveChild(parent.SelectSingleNode(CustomNode.Name));
SourceProv.Refresh();
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty, binding);
}
public XmlDataProvider SourceProv { get; set; }
public Node CustomNode { get; set; }
public String XPath { get; set; }
private Binding binding { get; set; }
}
public class NodeAvailableConverter : IValueConverter
{
private static NodeAvailableConverter _instance;
public static NodeAvailableConverter Instance
{
get
{
if (_instance == null)
_instance = new NodeAvailableConverter();
return _instance;
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
[ContentProperty("Attributes")]
public class Node
{
public string Name { get; set; }
private List<Attribute> _attributes;
public List<Attribute> Attributes { get
{
if (_attributes == null)
_attributes = new List<Attribute>();
return _attributes;
} }
}
public class Attribute
{
public string Name { get; set; }
public string Value { get; set; }
}
[ContentProperty(“CustomNode”)]
公共类MyBehavior:行为
{
受保护的覆盖无效附加()
{
base.onatached();
绑定=新绑定();
binding.XPath=XPath+“/”+CustomNode.Name;
binding.Mode=BindingMode.OneWay;
binding.Converter=NodeAvailableConverter.Instance;
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty,binding);
AssociatedObject.Click+=新建路由EventHandler(AssociatedObject\u Click);
SourceProv.Refresh();
}
作废关联对象\u单击(对象发送者,路由目标)
{
var parent=SourceProv.Document.SelectSingleNode(XPath);
if(AssociatedObject.IsChecked==true)
{
var newelement=SourceProv.Document.CreateElement(CustomNode.Name);
foreach(CustomNode.Attributes中的var at)
SetAttribute(at.Name,at.Value);
parent.AppendChild(新元素);
}
else if(AssociatedObject.IsChecked==false)
parent.RemoveChild(parent.SelectSingleNode(CustomNode.Name));
SourceProv.Refresh();
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty,binding);
}
公共XmlDataProvider SourceProv{get;set;}
公共节点CustomNode{get;set;}
公共字符串XPath{get;set;}
私有绑定{get;set;}
}
公共类NodeAvailableConverter:IValueConverter
{
私有静态节点AvailableConverter\u实例;
公共静态NodeAvailableConverter实例
{
得到
{
if(_instance==null)
_实例=新的NodeAvailableConverter();
返回_实例;
}
}
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
返回值!=null;
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
[内容属性(“属性”)]
公共类节点
{
公共字符串名称{get;set;}
私有列表属性;
公共列表属性{get
{
如果(_attributes==null)
_属性=新列表();
返回_属性;
} }
}
公共类属性
{
公共字符串名称{get;set;}
公共字符串值{get;set;}
}
现在这整件事看起来一点也不好,但是完成了任务。
但它确实揭示了一些奇怪的行为:
非常尴尬。。。如果有人能澄清任何问题,我们将不胜感激。如果有人感兴趣,我会提出以下建议: XAML:
<Window.Resources>
<local:NodeAvailableConverter x:Key="MyConverter"/>
<XmlDataProvider x:Key="xmlsource">
<x:XData>
<main xmlns="">
<sub/>
</main>
</x:XData>
</XmlDataProvider>
</Window.Resources>
<DockPanel DataContext="{Binding Source={StaticResource xmlsource}}">
<CheckBox Content="CheckBox1" DockPanel.Dock="Top">
<i:Interaction.Behaviors>
<local:MyBehavior SourceProv="{StaticResource xmlsource}" XPath="main">
<local:Node Name="sub">
<local:Attribute Name="yeah" Value="added1"/>
</local:Node>
</local:MyBehavior>
</i:Interaction.Behaviors>
</CheckBox>
<CheckBox Content="CheckBox2" DockPanel.Dock="Top">
<i:Interaction.Behaviors>
<local:MyBehavior SourceProv="{StaticResource xmlsource}" XPath="main">
<local:Node Name="sub">
<local:Attribute Name="yeah" Value="added2"/>
</local:Node>
</local:MyBehavior>
</i:Interaction.Behaviors>
</CheckBox>
<Label Content="{Binding OuterXml}" />
</DockPanel>
行为:
[ContentProperty("CustomNode")]
public class MyBehavior : Behavior<CheckBox>
{
protected override void OnAttached()
{
base.OnAttached();
binding = new Binding();
binding.XPath = XPath + "/" + CustomNode.Name;
binding.Mode = BindingMode.OneWay;
binding.Converter = NodeAvailableConverter.Instance;
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty, binding);
AssociatedObject.Click += new RoutedEventHandler(AssociatedObject_Click);
SourceProv.Refresh();
}
void AssociatedObject_Click(object sender, RoutedEventArgs e)
{
var parent = SourceProv.Document.SelectSingleNode(XPath);
if(AssociatedObject.IsChecked==true)
{
var newelement = SourceProv.Document.CreateElement(CustomNode.Name);
foreach (var at in CustomNode.Attributes)
newelement.SetAttribute(at.Name, at.Value);
parent.AppendChild(newelement);
}
else if (AssociatedObject.IsChecked == false)
parent.RemoveChild(parent.SelectSingleNode(CustomNode.Name));
SourceProv.Refresh();
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty, binding);
}
public XmlDataProvider SourceProv { get; set; }
public Node CustomNode { get; set; }
public String XPath { get; set; }
private Binding binding { get; set; }
}
public class NodeAvailableConverter : IValueConverter
{
private static NodeAvailableConverter _instance;
public static NodeAvailableConverter Instance
{
get
{
if (_instance == null)
_instance = new NodeAvailableConverter();
return _instance;
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
[ContentProperty("Attributes")]
public class Node
{
public string Name { get; set; }
private List<Attribute> _attributes;
public List<Attribute> Attributes { get
{
if (_attributes == null)
_attributes = new List<Attribute>();
return _attributes;
} }
}
public class Attribute
{
public string Name { get; set; }
public string Value { get; set; }
}
[ContentProperty(“CustomNode”)]
公共类MyBehavior:行为
{
受保护的覆盖无效附加()
{
base.onatached();
绑定=新绑定();
binding.XPath=XPath+“/”+CustomNode.Name;
binding.Mode=BindingMode.OneWay;
binding.Converter=NodeAvailableConverter.Instance;
AssociatedObject.SetBinding(CheckBox.IsCheckedProperty,binding);
AssociatedObject.Click+=新建路由EventHandler(AssociatedObject\u Click);
SourceProv.Refresh();
}