一个依赖项属性的应用

前端之家收集整理的这篇文章主要介绍了一个依赖项属性的应用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一种应用方法是使用依赖项属性代替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;
}


此处依赖项属性的应用只是更方便的为用户提供功能,并没有扩展,要想真正扩展控件的功能,恐怕要做的还有很多。

不知此处的应用是否正确,合理,符合依赖项属性的目的,如有高见,请不吝赐教。

猜你在找的设计模式相关文章