MVVM WPF ComboBox SelectedItem Binding not activated inside datagrid

穿精又带淫゛_ 提交于 2021-02-04 14:49:26

问题


I have struggled to save my combobox selected value when operating inside a datagrid. When I make a test solution with no datagrid things are working ok. The context are person names with associated countries. The countries are stored in a xml file. Here is a snapshot of the initial view:

Combobox with country names

You see here the (important parts of the)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>

This grid is populated from a PersonListViewModel, that has a private ObservableCollection<Person> _persons attribute that implements INotifyPropertyChanged and is the ItemsSource for the grid. You also see the SelectedItem="{Binding SelectedPerson}" in the grid. That part works OK.

The Person model class has CountryIndex (string, index in the xml-file, computed), Country (string, the country name) and now i implemented the XmlCountry attribute (XmlElement, the xmlnode in the xml-file. The xml file looks like this:

?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, ....

When I load the persons in the ViewModel constructor the person's country name is used to compute the country index that is used to set the initial values as you see in the screen shot. i achieved this by using the SelectedIndex="{Binding CountryIndex}" in the xaml above.

And then the problem started; I can not get the selection of countries in the combobox to call anything on the Person model OR the PersonListViewModel. I have tried almost anything ... :P

It is obvious that the key to the solution is this binding in the combobox:

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

The property 'XmlCountry' here resides in the Person model. I have tried to put it in the PersonListViewModel with no luck. The "Save Person" button works ok - it takes the "SelectedPerson" bound property and sends to the database. Except that it does not get the updated combobox value.

I would apperciate any help on the SelectedItem/SelectedIndex binding in the combobox. And also other suggestions: Do I need a PersonViewModel to wrap the Person model class maybe? Should I make a "AllCountries" attribute on my PersonListViewModel from the xml-file and use that instead of the xml-file directly?

Thanks a lot in advance!

UPDATE:

As I suspected: The devil was in the SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}" setting.

When i changed to:

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

everything works fine. I am now passing the right data to my "Save Person" method. However; it's the first time I have had to set UpdateSourceTrigger to keep view and viewmodel in synch ....


回答1:


Just para-quoting the update from the question above and putting it inside an actual answer.

The devil was in the SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}" setting.

When I change the Selected item binding to:

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

... everything works fine.



来源:https://stackoverflow.com/questions/18473674/mvvm-wpf-combobox-selecteditem-binding-not-activated-inside-datagrid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!