MVVM WPF ComboBox SelectedItem 绑定未在数据网格内激活 [英] MVVM WPF ComboBox SelectedItem Binding not activated inside datagrid

查看:23
本文介绍了MVVM WPF ComboBox SelectedItem 绑定未在数据网格内激活的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在数据网格中操作时,我一直在努力保存我的组合框选择的值.当我制作没有数据网格的测试解决方案时,一切正常.上下文是具有关联国家的人名.国家/地区存储在 xml 文件中.这是初始视图的快照:

您在这里看到了(重要部分)PersonList.xaml:

<XmlDataProvider x:Key="Dataxml";源 =PropertiesAllCountries.xml";/><model:Person x:Key=Person"/></UserControl.Resources><UserControl.DataContext><viewModel:PersonListViewModel/></UserControl.DataContext><DataGrid ItemsSource="{绑定人员}";AutoGenerateColumns=假"IsReadOnly=假"CanUserAddRows=假"SelectionUnit=FullRow"SelectedItem={绑定SelectedPerson}";><DataGrid.Columns><DataGridTextColumn Header="Name";绑定={绑定名称}"CanUserSort="true"></DataGridTextColumn><DataGridTemplateColumn Header="Country"><DataGridTemplateColumn.CellTemplate><数据模板><组合框宽度=150"SelectedValuePath=国家"IsSynchronizedWithCurrentItem=真"ItemsSource={绑定源={StaticResource Dataxml},XPath=/countries/country}";SelectedIndex={绑定国家索引}";SelectedItem={绑定路径=XmlCountry,模式=TwoWay}"><ComboBox.ItemTemplate><数据模板><文本块><TextBlock.Text><MultiBinding StringFormat="{}{0}, {1}"><绑定XPath=名称"/><绑定XPath=iso"/></多重绑定></TextBlock.Text></TextBlock></数据模板></ComboBox.ItemTemplate></组合框></数据模板></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn></DataGrid.Columns></DataGrid>

这个网格是从一个 PersonListViewModel 填充的,它有一个私有的 ObservableCollection_persons 属性,用于实现 INotifyPropertyChanged 并且是网格的 ItemsSource.您还可以在网格中看到 SelectedItem="{Binding SelectedPerson}".那部分工作正常.

Person 模型类具有 CountryIndex(字符串,xml 文件中的索引,已计算),Country(字符串,国家名称),现在我实现了 XmlCountry 属性(XmlElement,xml 文件中的 xmlnode.xml文件看起来像这样:

?xml version="1.0";编码=utf-8"?><国家><国家><iso>AF</iso><name>阿富汗</name></国家><国家><iso>AL</iso><name>阿尔巴尼亚</name></国家><国家><iso>DZ</iso><name>阿尔及利亚</name></国家><国家><iso>AS</iso><name>美属萨摩亚</name></国家><国家><iso>AD</iso><name>安道尔</name></国家>等等等等……

当我在 ViewModel 构造函数中加载人员时,人员的国家/地区名称用于计算用于设置初始值的国家/地区索引,如屏幕截图所示.我通过在上面的 xaml 中使用 SelectedIndex="{Binding CountryIndex}" 来实现这一点.

然后问题就开始了;我无法在组合框中选择国家/地区来调用 Person 模型或 PersonListViewModel 上的任何内容.我几乎尝试过任何东西......:P

很明显,解决方案的关键是组合框中的这个绑定:

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

此处的属性XmlCountry"位于 Person 模型中.我试图将它放在 PersonListViewModel 中,但没有运气.救人"按钮工作正常 - 它需要SelectedPerson";绑定属性并发送到数据库.除了它没有获得更新的组合框值.

我希望对组合框中的 SelectedItem/SelectedIndex 绑定提供任何帮助.还有其他建议:我是否需要一个 PersonViewModel 来包装 Person 模型类?我应该制作一个AllCountries"吗?从 xml 文件中删除我的 PersonListViewModel 上的属性并直接使用它而不是 xml 文件?

更新:

正如我所怀疑的:问题在于 SelectedItem={Binding Path=XmlCountry, Mode=TwoWay}" 设置.

当我改为:

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

一切正常.我现在正在将正确的数据传递给我的Save Person"方法.然而,这是我第一次必须设置 UpdateSourceTrigger 以保持视图和视图模型同步......

解决方案

只是引用上述问题的更新并将其放入实际答案中.

<块引用>

魔鬼在 SelectedItem="{Binding Path=XmlCountry,Mode=TwoWay}"设置.

当我将 Selected item 绑定更改为:

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

<块引用>

...一切正常.

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:

You see here the (important parts of the)PersonList.xaml:

<UserControl.Resources>
        <XmlDataProvider x:Key="Dataxml" Source="PropertiesAllCountries.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 cannot 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?

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 the view and viewmodel in synch....

解决方案

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.

这篇关于MVVM WPF ComboBox SelectedItem 绑定未在数据网格内激活的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆