MVVM WPF ComboBox SelectedItem 绑定未在数据网格内激活
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18473674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVVM WPF ComboBox SelectedItem Binding not activated inside datagrid
提问by JorgenH
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:
在数据网格中操作时,我一直在努力保存我的组合框选择的值。当我制作没有数据网格的测试解决方案时,一切正常。上下文是具有关联国家的人名。国家/地区存储在 xml 文件中。这是初始视图的快照:


You see here the (important parts of the)PersonList.xaml:
您在此处看到(重要部分)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> _personsattribute that implements INotifyPropertyChanged and is the ItemsSource for the grid. You also see the SelectedItem="{Binding SelectedPerson}"in the grid. That part works OK.
此网格由 PersonListViewModel 填充,该模型具有ObservableCollection<Person> _persons实现 INotifyPropertyChanged的私有属性,并且是网格的 ItemsSource。您还可以SelectedItem="{Binding SelectedPerson}"在网格中看到。那部分工作正常。
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:
Person 模型类具有 CountryIndex(字符串,xml 文件中的索引,已计算),Country(字符串,国家名称),现在我实现了 XmlCountry 属性(XmlElement,xml 文件中的 xmlnode。xml 文件看起来像这个:
?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.
当我在 ViewModel 构造函数中加载人员时,人员的国家/地区名称用于计算用于设置初始值的国家/地区索引,如屏幕截图所示。我通过SelectedIndex="{Binding CountryIndex}"在上面的 xaml 中使用 来实现这一点。
And then the problem started; I can not get the selection of countries in the combobox to call anything on the Personmodel OR the PersonListViewModel. I have tried almost anything ... :P
然后问题就开始了;我无法在组合框中选择国家/地区来调用Person模型或PersonListViewModel. 我几乎尝试过任何东西......: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 Personmodel. I have tried to put it in the PersonListViewModelwith 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.
此处的属性“XmlCountry”位于Person模型中。我试图把它放在PersonListViewModel没有运气的地方。“Save Person”按钮工作正常——它接受“SelectedPerson”绑定属性并发送到数据库。除了它没有获得更新的组合框值。
I would apperciate any help on the SelectedItem/SelectedIndexbinding in the combobox. And also other suggestions: Do I need a PersonViewModelto wrap the Personmodel class maybe? Should I make a "AllCountries" attribute on my PersonListViewModelfrom the xml-file and use that instead of the xml-file directly?
我希望SelectedItem/SelectedIndex对组合框中的绑定有任何帮助。还有其他建议:我是否需要PersonViewModel包装Person模型类?我应该PersonListViewModel从 xml 文件中创建“AllCountries”属性并直接使用它而不是 xml 文件吗?
Thanks a lot in advance!
非常感谢!
UPDATE:
更新:
As I suspected: The devil was in the SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}"setting.
正如我所怀疑的:魔鬼就在 SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}"环境中。
When i changed to:
当我改为:
SelectedItem="{Binding XmlCountry, **UpdateSourceTrigger=PropertyChanged**}"
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 UpdateSourceTriggerto keep view and viewmodel in synch ....
一切正常。我现在将正确的数据传递给我的“Save Person”方法。然而; 这是我第一次必须设置UpdateSourceTrigger以保持视图和视图模型同步......
回答by ouflak
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 Path=XmlCountry, Mode=TwoWay}" 设置。
当我将 Selected item 绑定更改为:
SelectedItem="{Binding XmlCountry, **UpdateSourceTrigger=PropertyChanged**}"
... everything works fine.
...一切正常。

