加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

一个依赖项属性的应用

发布时间:2020-12-13 20:01:02 所属栏目:百科 来源:网络整理
导读:一种应用方法是使用依赖项属性代替INotifyPropertyChanged接口,将界面绑定的数据源属性声明为依赖项属性,就可以自动更新到界面了,使用了wpf的内置机制,之前有一篇文章写了一个例子。 今天写的应用是重写一个控件,新空间使用依赖项属性来扩展wpf内置控件

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


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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读