Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.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# 在XAML中数据绑定到XML:如何附加新的XmlNode?_C#_Wpf_Xml_Data Binding_Xaml - Fatal编程技术网

C# 在XAML中数据绑定到XML:如何附加新的XmlNode?

C# 在XAML中数据绑定到XML:如何附加新的XmlNode?,c#,wpf,xml,data-binding,xaml,C#,Wpf,Xml,Data Binding,Xaml,到目前为止,我所发现的关于数据绑定到XML的一切似乎都只是绑定到一个固定的XML结构。如果有人能给我指点方向,那就太好了。到目前为止,我尝试的每件事都显得很尴尬 这就是我想做的: 将复选框的选中状态绑定到XML中的节点。 因此,将检查XML中是否存在此特定节点,如果不存在则取消选中 对于单向绑定,这并不难(使用返回“value!=null”的转换器绑定到节点) 现在,我还希望看到这个特定节点添加到基础XmlDocument中或从中删除 有没有一个简单的方法可以做到这一点 到目前为止,我尝试的是单

到目前为止,我所发现的关于数据绑定到XML的一切似乎都只是绑定到一个固定的XML结构。如果有人能给我指点方向,那就太好了。到目前为止,我尝试的每件事都显得很尴尬

这就是我想做的:

将复选框的选中状态绑定到XML中的节点。 因此,将检查XML中是否存在此特定节点,如果不存在则取消选中

对于单向绑定,这并不难(使用返回“value!=null”的转换器绑定到节点)

现在,我还希望看到这个特定节点添加到基础XmlDocument中或从中删除

有没有一个简单的方法可以做到这一点

到目前为止,我尝试的是单向绑定并添加CheckedChanged Eventhandler来处理添加/删除部分。这方面的代码很糟糕,它不会更新到这个XmlDataProvider的绑定

作为一个一般且简化的问题:在WPF中将新的XmlNodes添加到绑定的Xml结构中的好方法是什么


感谢您的帮助

据我所知,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;}
}
现在这整件事看起来一点也不好,但是完成了任务。 但它确实揭示了一些奇怪的行为:

  • 每次触发Click事件时,绑定似乎都未设置(这就是我每次再次设置它的原因)

  • 在clickhandler执行之前,必须调用XmlDataProvider的Refresh方法一次,因为当第一次执行Refresh时,似乎将原始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();
    }