0

这是我的 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>

这是我的 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>

上面的代码将联系人方法显示为组合框。将 XML Selected Attribute 设置为 true 的 ContactMethod 在组合框中预选并在启动时显示。

它看起来像这样:

这是它的样子

我使用以下方法保存数据:

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

此方法更改 ContactMethod 的值,而不是 Selected 属性。

如果您选择Mobile并单击 [提交],结果如下所示:

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

Selected在Attribute 等于 true的情况下,更改将保持不变。控件绑定的值被覆盖。

期望的结果:它应该是这样的:

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

问题: 如何更改当前选中项的选中属性?是否可以保留使用所需的 xml 数据结构所做的更改?

4

1 回答 1

1

你为什么不做这样的事情:而不是拥有多个 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>

然后像这样绑定你的 ComboBox:

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

另一个不更改源 XML 结构的选项:想法是在持久性时更改 XML,将选定的属性标志设置为ComboBox SelectedValue

将您的方法更改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");
    }

你的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>  
于 2013-04-02T16:42:30.440 回答