2013-08-27 1 views
11

Ich habe Mühe, meine Combobox ausgewählten Wert beim Betrieb in einem Datagrid zu speichern. Wenn ich eine Testlösung ohne DataGrid mache, funktionieren die Dinge gut. Der Kontext sind Personennamen mit assoziierten Ländern. Die Länder werden in einer XML-Datei gespeichert. Hier ist eine Momentaufnahme der ursprünglichen Ansicht:MVVM WPF ComboBox SelectedItem Bindung nicht aktiviert in Datagrid

Combobox with country names

Sie sehen hier die (wichtige Teile der) PersonList.xaml:

<UserControl.Resources> 
     <XmlDataProvider x:Key="Dataxml" Source="\Properties\AllCountries.xml" /> 
     <model:Person x:Key="Person"/> 
    </UserControl.Resources> 
    <UserControl.DataContext> 
     <viewModel:PersonListViewModel /> 
    </UserControl.DataContext> 

<DataGrid ItemsSource="{Binding Persons}" AutoGenerateColumns="False" IsReadOnly="False" CanUserAddRows="False" SelectionUnit="FullRow" SelectedItem="{Binding SelectedPerson}" > 
         <DataGrid.Columns> 
          <DataGridTextColumn Header="Name" Binding="{Binding Name}" CanUserSort="true" ></DataGridTextColumn> 
          <DataGridTemplateColumn Header="Country"> 
           <DataGridTemplateColumn.CellTemplate> 
            <DataTemplate> 
             <ComboBox 
               Width="150" 
               SelectedValuePath="country" 
               IsSynchronizedWithCurrentItem="True" 
               ItemsSource="{Binding Source={StaticResource Dataxml}, XPath=/countries/country}" 
               SelectedIndex="{Binding CountryIndex}" 
               SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}"> 
              <ComboBox.ItemTemplate> 
               <DataTemplate> 
                <TextBlock> 
                 <TextBlock.Text> 
                  <MultiBinding StringFormat="{}{0}, {1}"> 
                   <Binding XPath="name" /> 
                   <Binding XPath="iso" /> 
                  </MultiBinding> 
                 </TextBlock.Text> 
                </TextBlock> 
               </DataTemplate> 
              </ComboBox.ItemTemplate> 
             </ComboBox> 
            </DataTemplate> 
           </DataGridTemplateColumn.CellTemplate> 
          </DataGridTemplateColumn> 
         </DataGrid.Columns> 
        </DataGrid> 

Dieses Gitter aus einem PersonListViewModel bevölkert ist, das eine hat privates ObservableCollection<Person> _persons Attribut, das INotifyPropertyChanged implementiert und ItemsSource für das Grid ist. Sie sehen auch die SelectedItem="{Binding SelectedPerson}" im Raster. Dieser Teil funktioniert OK.

Die Personenmodell Klasse hat CountryIndex (String, Index in der XML-Datei, berechnet), Land (String, der Ländername) und jetzt habe ich das XmlCountry Attribut (XmlElement, der XMLNode in der XML-Datei) implementiert xML-Datei sieht wie folgt aus:.

?xml version="1.0" encoding="utf-8"?> 
<countries> 
    <country> 
    <iso>AF</iso> 
    <name>Afghanistan</name> 
    </country> 
    <country> 
    <iso>AL</iso> 
    <name>Albania</name> 
    </country> 
    <country> 
    <iso>DZ</iso> 
    <name>Algeria</name> 
    </country> 
    <country> 
    <iso>AS</iso> 
    <name>American Samoa</name> 
    </country> 
    <country> 
    <iso>AD</iso> 
    <name>Andorra</name> 
    </country> 
etc, etc, .... 

Wenn ich lade die Personen im Ansichtsmodell Konstruktor der Landes Name der Person verwendet wird, um den Länderindex zu berechnen, die verwendet wird, um die Anfangswerte zu setzen, wie Sie im Screenshot sehen i erreicht dies durch die Verwendung der SelectedIndex="{Binding CountryIndex}" in der XAML oben

Und dann begann das Problem, ich kann nicht t Die Auswahl der Länder in der Combobox, um irgendetwas auf dem Person Modell ODER die PersonListViewModel zu nennen. Ich habe fast alles versucht ...: P

Es ist offensichtlich, dass der Schlüssel zur Lösung ist dies in der Combobox Bindung:

SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}" 

Die Eigenschaft ‚XmlCountry‘ hier wohnt im Person Modell. Ich habe versucht, es in die PersonListViewModel ohne Glück zu setzen. Die Schaltfläche "Person speichern" funktioniert einwandfrei. Sie übernimmt die gebundene Eigenschaft "SelectedPerson" und sendet sie an die Datenbank. Außer, dass es den aktualisierten Combobox-Wert nicht erhält.

Ich würde jede Hilfe auf der SelectedItem/SelectedIndex Bindung in der Combobox apperciate. Und auch andere Vorschläge: Brauche ich eine PersonViewModel um die Person Modellklasse vielleicht zu wickeln? Sollte ich ein "AllCountries" -Attribut auf meiner PersonListViewModel aus der XML-Datei machen und das anstelle der XML-Datei direkt verwenden?

Vielen Dank im Voraus!

UPDATE:

Wie ich vermutete: Der Teufel war in der SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}" Einstellung.

Wenn ich geändert:

SelectedItem="{Binding XmlCountry, **UpdateSourceTrigger=PropertyChanged**}"

alles funktioniert. Ich gebe nun die richtigen Daten an meine "Save Person" -Methode weiter. Jedoch; es ist das erste Mal, dass ich UpdateSourceTrigger setzen musste, um Ansicht und viewmodel synchron zu halten ....

Antwort

10

Para-Zitat das Update von der obigen Frage und setzen es in eine tatsächliche Antwort.

Der Teufel war in der SelectedItem = "{Binding Path = XmlCountry, Mode = TwoWay}" -Einstellung.

Wenn ich das ausgewählte Element ändern Bindung an:

SelectedItem="{Binding XmlCountry, **UpdateSourceTrigger=PropertyChanged**}" 

... alles funktioniert.