2013-04-02 2 views
0

Это мой XAML пример кода:Изменение атрибута XML в Datasource через ComboBox TwoWay Связывание

<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> 

Код выше отображает методы контакты как выпадающий список , ContactMethod, который имеет XML Selected Attribute, установленный в true, предварительно выбран в выпадающем списке и отображается при запуске.

Это выглядит следующим образом:

This is how it looks like

Я использую следующий метод для сохранения данных:

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

Этот метод изменяет значение ContactMethod и не выбранный атрибут.

При выборе Mobile и нажмите кнопку [отправить] результат выглядит следующим образом:

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

Это изменение сохраняется где Selected атрибут равен действительности. Значение, на которое был связан элемент управления, перезаписывается.

Желаемый результат: он должен выглядеть следующим образом:

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

Вопрос: Как изменить выбранный атрибут выбранного в данный момент элемента? Можно ли сохранить изменения, сделанные с помощью желаемой структуры данных xml?

ответ

1

Почему бы вам не сделать что-то вроде этого: вместо того, чтобы иметь несколько выбранных атрибутов просто создать Selected атрибут ContactMethods элемента:

<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 во время сохранения, установив выделенный флаг атрибута на ComboBoxSelectedValue:

Измените метод 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> 
+0

Да, я знаю, что будет легко. К сожалению, я должен использовать данный источник данных. Я не могу влиять на структуру данных. – Joel

+0

Проверьте мою другую альтернативу, просто изменив ответ –

+0

. Я бы предпочел решение с меньшим количеством кода, потому что весь XAML/CodeBehind должен генерироваться автоматически во время выполнения. Я подожду несколько дней, чтобы увидеть, есть ли другие способы, если я не буду отмечать ваше сообщение как ответ. – Joel

Смежные вопросы