一个依赖项属性的应用

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


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

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




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值