WPF 中级联下拉列表和列表框多选选项






4.85/5 (11投票s)
尝试展示在 WPF 中使用 MVVM 模式通过级联下拉框/组合框和列表框绑定实现的灵活性

引言
很多时候,我们会遇到需要根据另一个下拉框或组合框的值来填充下拉框的情况。
有时,我们也需要根据多个选定的值来填充 Listbox
中的项目。
在本文中,我将展示一种使用 WPF 解决该问题的方法。
背景
WPF 非常酷,它具有出色的绑定功能,并且得到了 ModelView-ViewModel 模式的完美支持。
但是,在这里我不打算讨论 MVVM 模式的详细信息,因为有很多优秀的网站都提供了大量的相关内容,例如:
我将更多地关注如何使用 WPF 的模式来解决这个问题。
必备组件
- .NET Framework 3.5
关于 MVVM 模式的几点说明
用非常简单的语言描述 MVVM 的各个元素
- 模型:数据源
- 视图:UI 元素
- 视图模型:它位于模型和视图之间,并有助于绑定
关于应用程序
基本上,这里有两个小程序
- 简单的级联下拉框
- 简单的级联列表框
在这两种情况下,我都使用了 3 种类型的元素,即:国家/地区下拉框/列表框,然后是州/省下拉框/列表框,然后是城市下拉框/列表框。 区别在于,对于列表框,我们可以选择多个项目。
程序目标
在简单的级联下拉框中,州/省下拉框将根据所选国家/地区填充,而城市将根据所选州/省填充。 在简单的级联列表框中,概念与上述相同,不同之处在于用户可以选择多个选项。
代码解释
我有 3 个类,即 Country
、State
和 City
。 我还有一个 Datasource
类 (Datasource.cs)
datasource
是具有以下代码片段的模型
ObservableCollection<country> _country = new ObservableCollection<country>();
ObservableCollection<state> _state = new ObservableCollection<state>();
ObservableCollection<city> _city = new ObservableCollection<city>();
可以看出,我创建了 3 个 ObservableCollection
。
与列表相比,使用 ObservableCollection
的优势在于,当添加、删除项目或刷新整个列表时,它会提供通知。
datasource
如下
//For Country
private void CountryData()
{
_country.Add(new Country { CountryName = "India", CountryCode = "IN" });
_country.Add(new Country { CountryName = "USA", CountryCode = "US" });
_country.Add(new Country { CountryName = "Canada", CountryCode = "CA" });
_country.Add(new Country { CountryName = "Singapore", CountryCode = "SI" });
}
////////////////////////////////////////////////////////////////////////////
//For State
private void StateData()
{
_state.Add(new State { StateName = "IndState1",
CountryCode = "IN", StateCode = "INS1" });
_state.Add(new State { StateName = "IndState2",
CountryCode = "IN", StateCode = "INS2" });
_state.Add(new State { StateName = "IndState3",
CountryCode = "IN", StateCode = "INS3" });
_state.Add(new State { StateName = "IndState4",
CountryCode = "IN", StateCode = "INS4" });
_state.Add(new State { StateName = "USAState1",
CountryCode = "US", StateCode = "USS1" });
_state.Add(new State { StateName = "USAState2",
CountryCode = "US", StateCode = "USS2" });
_state.Add(new State { StateName = "USAState3",
CountryCode = "US", StateCode = "USS3" });
_state.Add(new State { StateName = "USAState4",
CountryCode = "US", StateCode = "USS4" });
_state.Add(new State { StateName = "CANState1",
CountryCode = "CA", StateCode = "CAS1" });
_state.Add(new State { StateName = "CANState2",
CountryCode = "CA", StateCode = "CAS2" });
_state.Add(new State { StateName = "CANState3",
CountryCode = "CA", StateCode = "CAS3" });
_state.Add(new State { StateName = "CANState4",
CountryCode = "CA", StateCode = "CAS4" });
_state.Add(new State { StateName = "SINGState1",
CountryCode = "SI", StateCode = "SIS1" });
_state.Add(new State { StateName = "SINGState2",
CountryCode = "SI", StateCode = "SIS2" });
_state.Add(new State { StateName = "SINGState3",
CountryCode = "SI", StateCode = "SIS3" });
_state.Add(new State { StateName = "SINGState4",
CountryCode = "SI", StateCode = "SIS4" });
}
////////////////////////////////////////////////////////////////////////////
//For City
private void CityData()
{
_city.Add(new City { CityName = "IndianState1City1", StateCode = "INS1" });
_city.Add(new City { CityName = "IndianState1City2", StateCode = "INS1" });
_city.Add(new City { CityName = "IndianState2City1", StateCode = "INS2" });
_city.Add(new City { CityName = "IndianState2City2", StateCode = "INS2" });
_city.Add(new City { CityName = "IndianState3City1", StateCode = "INS3" });
_city.Add(new City { CityName = "IndianState3City2", StateCode = "INS3" });
_city.Add(new City { CityName = "IndianState4City1", StateCode = "INS4" });
_city.Add(new City { CityName = "IndianState4City2", StateCode = "INS4" });
_city.Add(new City { CityName = "USAState1City1", StateCode = "USS1" });
_city.Add(new City { CityName = "USAState1City2", StateCode = "USS1" });
_city.Add(new City { CityName = "USAState2City1", StateCode = "USS2" });
_city.Add(new City { CityName = "USAState2City2", StateCode = "USS2" });
_city.Add(new City { CityName = "USAState3City1", StateCode = "USS3" });
_city.Add(new City { CityName = "USAState3City2", StateCode = "USS3" });
_city.Add(new City { CityName = "USAState4City1", StateCode = "USS4" });
_city.Add(new City { CityName = "USAState4City2", StateCode = "USS4" });
_city.Add(new City { CityName = "CanadaState1City1", StateCode = "CAS1" });
_city.Add(new City { CityName = "CanadaState1City2", StateCode = "CAS1" });
_city.Add(new City { CityName = "SingaporeState1City1", StateCode = "SIS1" });
_city.Add(new City { CityName = "SingaporeState1City2", StateCode = "SIS2" });
}
现在是 ModelView
,其名称为 StateCountryViewModel.cs。
该类继承自 INotifyPropertyChanged
接口。
它包含一个名为 PropertyChanged
的事件.
每当 ViewModel
对象上的属性发生更改时,它都会引发 PropertyChanged
事件,以将新值通知给 WPF 绑定系统。 收到该通知后,绑定系统会查询该属性,并且某些 UI 元素上的绑定属性会收到新值。
最后是视图部分,即 Window1.xaml。
视图的整个来源是视图模型(在本例中为 StateCountryViewModel
)。
通过使用 ItemsSource="{Binding PropertyName}"
语法(请注意,这是 ViewModel
公开的属性)在此处使用的项目上完成绑定,而值使用 DisplayMemberPath="PropertyName"
显示(请注意,这是 Class
公开的属性)。
结论
这只是尝试展示在 WPF 中使用 MVVM 模式绑定实现的灵活性。
历史
- 2009 年 5 月 10 日:首次发布