一种应用方法是使用依赖项属性代替INotifyPropertyChanged接口,将界面绑定的数据源属性声明为依赖项属性,就可以自动更新到界面了,使用了wpf的内置机制,之前有一篇文章写了一个例子。
今天写的应用是重写一个控件,新空间使用依赖项属性来扩展wpf内置控件的功能,不过我的这个控件更多是为了方便使用,类似于是老控件的一个对象,只用于某种特殊的表示方式,来源于一道面试题,两个combobox,一个是省名称,一个是市名称,当省的combobox选项改变时,市combobox列表也随之改变,用依赖项属性实现。
首先来展示一下,如果不使用依赖项属性,正常的做法
声明两个combobox,一个是省,一个是市
<ComboBox Grid.Row="0" Name="ProvienceComboBox" Height="30" ItemsSource="{Binding Path=Proviences}" SelectionChanged="ComboBox_SelectionChanged" SelectedValuePath="Id" DisplayMemberPath="Name" SelectedIndex="0"> </ComboBox> <ComboBox Grid.Row="1" Name="CityComboBox" Height="30" SelectedIndex="0" SelectedValuePath="Id" DisplayMemberPath="Name"> </ComboBox>
后台数据结构:
public class NotifyPropertyChangeBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName); PropertyChanged(this,e); } } } //这个省数据使用依赖项属性实现,是之前提到的依赖项属性的一种应用 方法 public class ProvienceInfo : DependencyObject { public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name",typeof(string),typeof(ProvienceInfo)); public ProvienceInfo(string s,int id) { Name = s; this.id = id; } private int id; public int Id { set { if (id != value) { id = value; } } get { return id; } } public string Name { set { //if (name != value) { SetValue(NameProperty,value); } } get { return GetValue(NameProperty).ToString(); } } private CityList citys; public CityList Citys { get { return citys; } set { if (citys != value) { citys = value; } } } }
//市使用notify接口实现 public class CityInfo : NotifyPropertyChangeBase { public CityInfo(string name) { this.name = name; } private string name; public string Name { set { if (name != value) { name = value; OnPropertyChanged("Name"); } } get { return name; } } } public class ProvienceList : ObservableCollection<ProvienceInfo> { } public class CityList : ObservableCollection<CityInfo> { }
专门为UI提供数据的数据类
public class Data {
//假数据 public Data() { proviences = new ProvienceList(); citys = new CityList(); string[] s = { "hebei","henan","shandong" }; string[][] cityArrar = new string[3][]; string[] hebeicity= { "shijiazhuang","baoding","tangshan" }; string[] henancity = { "zhengzhou","pingdingshan" }; string[] shandongcity = { "qingdao","jinan" }; cityArrar[0] = hebeicity; cityArrar[1] = henancity; cityArrar[2] = shandongcity; for (int i = 0; i < 3; i++) { ProvienceInfo pi = new ProvienceInfo(s[i],i); CityList cl = new CityList(); proviences.Add(pi); for (int j = 0; j < cityArrar[i].Length; j++) { cl.Add(new CityInfo(cityArrar[i][j])); } pi.Citys = cl; } } ProvienceList proviences; public ProvienceList Proviences { get { return proviences; } set { proviences = value; } } }
后台的数据源绑定
public MainWindow() { InitializeComponent(); data = new Data(); this.DataContext = data; //给控件设置datacontext } //当省级的combobox选项改变的时候变更市级combobox的数据源 private void ComboBox_SelectionChanged(object sender,SelectionChangedEventArgs e) { ComboBox cb = sender as ComboBox; object o = cb.SelectedValue; CityComboBox.ItemsSource = (cb.SelectedItem as ProvienceInfo).Citys; CityComboBox.SelectedIndex = 0; }
这样就可以实现功能了。
如果使用依赖项属性,我创建了一个新类,扩展combobox,该类中有一个citylist属性,用户只需要给改属性赋值或绑定,就可以显示 public class MyComboBox : ComboBox { public static readonly DependencyProperty cityListProperty = DependencyProperty.Register("cityList",typeof(CityList),typeof(MyComboBox),new PropertyMetadata(null,MyPropertyChangedCallback)); static void MyPropertyChangedCallback(DependencyObject d,DependencyPropertyChangedEventArgs e) { MyComboBox m = d as MyComboBox; if (m != null) { m.ItemsSource = m.cityList; //实际上citylist只是将itemsource封装起来了 m.SelectedIndex = 0; } } public MyComboBox() { this.DisplayMemberPath = "Name"; //限制了只能显示city的name,或者还有其他好的办法可以进行拓展? } public CityList cityList { get { return (CityList)GetValue(cityListProperty); } set { SetValue(cityListProperty,value); } } }
前台xaml,只需设置citylist
<local:MyComboBox x:Name="myComboBox" Grid.Row="3" cityList="{Binding Path=Citys}" SelectedIndex="0"/>
数据源中添加一个citys的数据,因为mycombobox中需要绑定,此处省略。
当省的选项改变时,只需改变mycombobox的citylist
private void ComboBox_SelectionChanged(object sender,SelectionChangedEventArgs e) { ComboBox cb = sender as ComboBox; myComboBox.cityList = (cb.SelectedItem as ProvienceInfo).Citys; }
此处依赖项属性的应用只是更方便的为用户提供功能,并没有扩展,要想真正扩展控件的功能,恐怕要做的还有很多。
不知此处的应用是否正确,合理,符合依赖项属性的目的,如有高见,请不吝赐教。 (编辑:安卓应用网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|