已经学习了好几天了,一个小例子让我豁然开朗,以下是我个人的一点理解:
由于WPF由XAML文件和c#文件组成的,c#负责逻辑处理,所以很多控件属性就会别修改,此时我们希望他能够反映到界面上,依赖项属性就能够做到这点。当然系统的控件的一般的属性都是依赖性的,我们不必担心,但在数据绑定的时候,我们会经常绑定到对象,这就要求对象的属性变化是也要通知到对象。通常可以采用PropertyChangedEventHandler来通知界面,如果在创建类的时候就把其属性写为依赖项属性就省去了这些麻烦,下面是一个小例子可以清楚的看到他们的区别:
XAML:
? <Window.Resources>????
??? <pd:Person x:Key="person" Name="shao"/>???<!--自定义的类的对象-->???
? </Window.Resources>
? <StackPanel>?
??? <ListBox x:Name="lbColor" Width="248" Height="56"? DataContext="{StaticResource person}">
????? <ListBoxItem Content="{Binding Path=Name}" MouseDoubleClick="OnMouseDoubleClick">?????
????? </ListBoxItem>
????? <ListBoxItem Content="Green"/>
??? </ListBox>
??? <TextBlock Width="248" Height="24" Text="You selected color:" />
??? <TextBlock Width="248" Height="24">
????? <TextBlock.Text>
??????? <Binding ElementName="lbColor" Path="SelectedItem.Content"/>
????? </TextBlock.Text>
??? </TextBlock>
? </StackPanel>
c#:
?private void OnMouseDoubleClick(object sender,MouseButtonEventArgs e)
??????? {???????????
??????????? Person person = (Person)this.Resources["person"];
??????????? person.Name = "changed";
??????? }
自定义的类的属性如果定义的普通类型:
public class Person?
??? {
??????? public string name;
??????? public Person()
??????? {
??????? }
??????? public Person(string _name)
??????? {
??????????? this.Name = _name;
??????? }
??????? public string Name
??????? {
??????????? get { return name; }
??????????? set?
??????????? {
??????????????? name = value;
??????????? }
??????? }???????
??? }
时,双击ListBoxItem时虽然person.Name变成了"changed",但是不会反应的界面,也就是说界面上根本就看不到。这时可以使用PropertyChangedEventHandler来通知界面:
public class Person?:INotifyPropertyChanged
??? {
??????? public string name;
??????? public event PropertyChangedEventHandler PropertyChanged;
??????? public Person()
??????? {
??????? }
?
??????? public Person(string _name)
??????? {
??????????? this.Name = _name;
??????? }
?
??????? public string Name
??????? {
??????????? get { return name; }
??????????? set
??????????? {
??????????????? name = value;
??????????????? // Call OnPropertyChanged whenever the property is updated
??????????????? OnPropertyChanged("Name");
??????????? }
??????? }
????????protected void OnPropertyChanged(string name)
??????? {
??????????? PropertyChangedEventHandler handler = PropertyChanged;
??????????? if (handler != null)
??????????? {
??????????????? handler(this,new PropertyChangedEventArgs(name));
??????????? }
??????? }
??? }
这也是通常用的方法,此时就可以反映到界面上,我们还可以使用依赖项属性来解决这个问题:
public class Person : DependencyObject
??? {
??????? public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name",typeof(string),typeof(Person));
??????? public Person()
??????? {
??????? }
??????? public Person(string _name)
??????? {
??????????? this.Name = _name;
??????? }
??????? public string Name
??????? {
??????????? get { return (string)GetValue(NameProperty); }
??????????? set
??????????? {
??????????????? SetValue(NameProperty,value);
??????????? }
??????? }
??? }
该类中的Name属性就相当于Button中的Height等属性,在c#中改变时同样可以放映到桌面上。
看懂了这个例子应该就明白依赖项属性时怎么回事了,不过对于自定义类一般是不需要写依赖项属性的,使用第一种解决方法就可以了,当系统的默认控件满足不了需要而要重写一个控件继承默认控件时写一个依赖项属性时个很好的选择。
不过在多线程中可能会出问题,这点我不是很清楚。