Я пытаюсь сохранить выбранное значение combobox при работе внутри datagrid. Когда я делаю тестовое решение без каких-либо данных, все работает нормально. Контекст - это имена людей со связанными странами. Страны хранятся в XML файле. Вот снимок исходного вида:
Вы видите здесь (важные части) 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>
Эта сетка заполняется из PersonListViewModel, которая имеет частный атрибут ObservableCollection<Person> _persons
, который реализует INotifyPropertyChanged и является ItemsSource для сетки. Вы также видите SelectedItem="{Binding SelectedPerson}"
в сетке. Эта часть работает нормально.
Класс модели Person имеет CountryIndex (строка, индекс в xml файле, вычисленный), Country (строка, название страны), и теперь я реализовал атрибут XmlCountry (XmlElement, 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, ....
Когда я загружаю людей из конструктора ViewModel, имя страны страны используется для вычисления индекса страны, который используется для установки начальных значений, как вы видите на снимке экрана. Я достиг этого, используя SelectedIndex="{Binding CountryIndex}"
в вышеприведенном xaml.
И тогда проблема началась; Я не могу получить выделение стран в поле со списком для вызова чего-либо в модели Person
ИЛИ PersonListViewModel
. Я пробовал почти все...: P
Очевидно, что ключом к решению является эта привязка в поле со списком:
SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}"
Свойство "XmlCountry" здесь находится в модели Person
. Я попытался поместить его в PersonListViewModel
без везения. Кнопка "Сохранить человека" работает нормально - она берет свойство "SelectedPerson" и отправляет его в базу данных. За исключением того, что он не получает обновленное значение combobox.
Я бы применил любую помощь в привязке SelectedItem/SelectedIndex
в combobox. А также другие предложения: Нужно ли мне PersonViewModel
обернуть класс модели Person
? Должен ли я сделать атрибут "AllCountries" на моем PersonListViewModel
из xml файла и использовать это вместо XML файла напрямую?
Большое спасибо!
UPDATE:
Как я и подозревал: дьявол находился в настройке SelectedItem="{Binding Path=XmlCountry, Mode=TwoWay}"
.
Когда я изменил на:
SelectedItem="{Binding XmlCountry, **UpdateSourceTrigger=PropertyChanged**}"
все работает нормально. Теперь я передаю правильные данные методу "Сохранить человека". Однако; это первый раз, когда мне пришлось установить UpdateSourceTrigger
, чтобы синхронизировать просмотр и viewmodel....