Поделиться через


Привязка поля со списком на основе значения первого поля со списком в MVVM

В этой публикации я покажу, как можно привязать второе поле со списком на основе значения "Коморские Острова" первого поля со списком с помощью MVVM. При разработке веб-приложений и приложений для рабочих столов часто встречается сценарий, когда требуется заполнить поле со списком в зависимости от значения родительского поля со списком, например в приложении с элементами управления "поле со списком" для стран и для областей стран, когда пользователь может выбрать в одном поле со списком название страны, и на основе этого названия заполняется список областей для второго поля со списком, либо путем извлечения из базы данных, либо путем фильтрации локально сохраненных записей. На следующем рисунке показано окно, содержащее два элемента управления "поле со списком", одно для страны и второе для области, и две кнопки, одна для сохранения, используемая для просмотра выбранного значения из списка стран, а вторая для закрытия окна.

Теперь давайте начнем работу с кодом. Для этой модели я определяю два класса — для стран и для областей. Класс стран имеет два свойства — название страны и код страны, который используется для поиска области в списке областей и имеет тип int. Свойство названия страны используется для отображения в поле со списком и для функции, которая будет возвращать все названия стран. Второй класс предназначен для областей и также имеет два свойства — идентификатор страны (относящийся к родительской стране) и имя области, которое отображается в элементе управления "поле со списком" для областей. Для класса областей имеются две функции; одна будет возвращать все области, а с помощью второй будут возвращаться области, соответствующие коду страны, который передается в качестве параметра.

ViewModel

Далее приводится код, который написан в данной модели просмотра. Я привожу здесь этот важный код, чтобы объяснить его. Можно видеть, что в коде имеется три свойства, одно из которых предназначено для списка имен стран, используемого для связывания элемента управления "поле со списком" стран. В нем нет никакого дополнительного кода, кроме get и set, поскольку я хочу привязать поле со списком стран только один раз. Второе свойство — это SelectedCountryName, которое используется для привязки значения SelectedValue из списка имен стран путем порождения события RaisedPropertyChanged, поскольку я хочу выбирать значения областей в зависимости от выбранной страны.

public List<CountryNames> CountryNameList { get; set; }
public CountryNames SelectedCountryName
{
 get{return selectedCountryName;}
 set
{
selectedCountryName = value;
RaisePropertyChanged("SelectedCountryName");
}
}
public List<StateNames> StateNameList
{
 get{return stateNameList;}
 set
{
stateNameList = value;
RaisePropertyChanged("StateNameList");
}
}

Третье свойство, которое я хочу здесь объяснить, это StateNameList, и можно видеть, что я вызываю здесь обработчик события изменения свойства, поскольку значение этого списка будет изменяться каждый раз при выборе новой страны в поле со списком стран.

Представление

Для представления я выбрал только поле со списком стран, чтобы объяснить, как можно привязать это поле со списком и затем получить выбранное в этом поле значение в модели представления. Здесь можно видеть, что я привязываю свойство ItemSource элемента управления "поле со списком" к свойству CountryNameList, которое задано в модели представления, и список возврата.

< ComboBox Grid.Column="1" Grid.Row="1" Margin="1,2,5,2" ItemsSource="{Binding CountryNameList}" DisplayMemberPath="CountryName" SelectedValue="{Binding Path=SelectedCountryName,Mode=TwoWay}"/>

Чтобы извлечь выбранное значение обратно в модель представления, я связываю свойство SelectedValue поля списка стран со свойством SelectedCountryName и устанавливаю двусторонний режим. Теперь, когда название страны изменяется, выбранное значение поля со списком тоже изменяется. Я вызвал событие изменения в модели представления, а также проверил в этом событии имя свойства, которое передается в SelectedCountryName, после чего выбирается список названий областей. Надеюсь, у вас есть идеи, как можно привязать это поле со списком и извлечь выбранное значение. Исходный код можно загрузить здесь.