简体   繁体   English

通过ComboBox TwoWay绑定更改数据源中的XML属性

[英]Change XML attribute in Datasource via ComboBox TwoWay Binding

This is my XAML sample code: 这是我的XAML示例代码:

<Grid>
    <Grid.DataContext>
        <XmlDataProvider x:Name="DataProvider" Source="datacontext.xml" XPath="/"  />
    </Grid.DataContext>
    <ComboBox Name="combobox1" Width="100" Height="25" ItemsSource="{Binding XPath=Contact/ContactMethods//*}">
        <ComboBox.SelectedValue>
            <Binding XPath="Contact\ContactMethods/*[@Selected='True']" NotifyOnSourceUpdated="True" NotifyOnTargetUpdated="True" />
        </ComboBox.SelectedValue>
    </ComboBox>
</Grid>

This is my XML data source: 这是我的XML数据源:

<Contact ShowsInterest="true">
  <Name>John</Name>
  <Lastname>Doe</Lastname>
  <ContactMethods>
    <ContactMethod Selected="False">Phone</ContactMethod>
    <ContactMethod Selected="False">Email</ContactMethod>
    <ContactMethod Selected="True">Letter</ContactMethod>
    <ContactMethod Selected="False">Mobile</ContactMethod>
  </ContactMethods>
</Contact>

The code above displays the contacts methods as the combobox. 上面的代码将联系人方法显示为组合框。 The ContactMethod which has the XML Selected Attribute set to true is preselected in the combobox and displayed at startup. 在组合框中预先选择了XML选定属性设置为true的ContactMethod,并在启动时显示。

It looks like this: 看起来像这样:

看起来像这样

I use the following method to save the data: 我使用以下方法保存数据:

private void OnSubmitClick(object sender, System.EventArgs eventArgs)
{
    DataProvider.Document.Save("datacontext.xml");
}

This method changes the value of the ContactMethod and not the Selected Attribute. 此方法更改ContactMethod的值,而不更改Selected Attribute的值。

If you select Mobile and click [submit] the result looks like this: 如果选择Mobile并单击[提交],结果将如下所示:

  <ContactMethods>
    <ContactMethod Selected="False">Phone</ContactMethod>
    <ContactMethod Selected="False">Email</ContactMethod>
    <ContactMethod Selected="True">Mobile</ContactMethod>
    <ContactMethod Selected="False">Mobile</ContactMethod>
  </ContactMethods>

The change is persisted where the Selected Attribute equals true. 当“ Selected属性”等于true时,更改将保留。 The value which the control was bound to is overwritten. 控件绑定到的值将被覆盖。

Desired Result: it should look like this: 所需的结果:应该看起来像这样:

  <ContactMethods>
    <ContactMethod Selected="False">Phone</ContactMethod>
    <ContactMethod Selected="False">Email</ContactMethod>
    <ContactMethod Selected="False">Letter</ContactMethod>
    <ContactMethod Selected="True">Mobile</ContactMethod>
  </ContactMethods>

Question: How do i change the Selected Attribute of the currently selected item? 问题:如何更改当前选定项目的“选定属性”? Is it possible to persist the changes made with the desired xml data structure? 是否可以保留所需的xml数据结构所做的更改?

Why don't you do something like this: instead of having multiple Selected attributes just create a Selected attribute in ContactMethods element: 为什么不做这样的事情:不是在具有多个Selected属性的情况下,而是在ContactMethods元素中创建Selected属性:

<Contact ShowsInterest="true">
  <Name>John</Name>
  <Lastname>Doe</Lastname>
  <ContactMethods Selected="Phone">
    <ContactMethod>Phone</ContactMethod>
    <ContactMethod>Email</ContactMethod>
    <ContactMethod>Letter</ContactMethod>
    <ContactMethod>Mobile</ContactMethod>
  </ContactMethods>
</Contact>

Then just bind your ComboBox like this: 然后像这样绑定您的ComboBox:

    <ComboBox Name="combobox1" Width="100" Height="25" ItemsSource="{Binding XPath=Contact/ContactMethods/ContactMethod}"
             IsSynchronizedWithCurrentItem="True" 
             SelectedValue="{Binding XPath=Contact/ContactMethods/@Selected}">
    </ComboBox>

Another option without changing the source XML structure : The idea is to alter the XML at the time of persistence setting the selected attribute flag to the ComboBox SelectedValue : 另一个不更改源XML结构的选项 :想法是在持久化时将XML更改为XML,将selected属性标志设置为ComboBox SelectedValue

Change your OnSubmitClick method to: 将您的OnSubmitClick方法更改为:

    private void OnSubmitClick(object sender, RoutedEventArgs e)
    {
        XElement xe = XElement.Load(new XmlNodeReader(DataProvider.Document));
        var elements = xe.Elements("ContactMethods").Elements("ContactMethod").ToList();
        var sel = combobox1.SelectedValue;
        foreach(XElement element in elements)
        {
            element.SetAttributeValue("Selected", (string)sel == element.Value ? "True" : "False");
        }
        xe.Save("datacontext.xml");
        //DataProvider.Document.Save("datacontext.xml");
    }

And your ComboBox definition to: 和您的ComboBox定义为:

       <ComboBox Name="combobox1" Width="100" Height="25" ItemsSource="{Binding XPath=Contact/ContactMethods/ContactMethod}"
             IsSynchronizedWithCurrentItem="True" 
             SelectedValue="{Binding XPath=Contact/ContactMethods/ContactMethod[@Selected\=\'True\'],Mode=OneTime}">
        </ComboBox>  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM