1、假设定义了一个MyButton类,它继承自Button,给他增加一个Text的属性:
public class MyButton : Button
{
static MyButton()
{
FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
metadata.PropertyChangedCallback += SpacePropertyChangedCallback;
metadata.DefaultValue = "Default Value";
metadata.Inherits = true;
//Inherits的值一定要设置为true,不然属性的值就不能被继承
SpaceProperty = DependencyProperty.Register(
"Space",typeof(string),
typeof(MyButton),
metadata);
}
public static readonly DependencyProperty SpaceProperty;
public string Space
{
get
{
return (string)GetValue(SpaceProperty);
}
set
{
SetValue(SpaceProperty, value);
}
}
private static void SpacePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var obj = d as MyButton;
obj.Content = obj.Space;
}
}
2、在MainWIndow.xaml文件中应用该Button:
这里写代码片
<Window x:Class="InheritDPDemo.SpaceWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:InheritDPDemo"
Title="SpaceWindow" Height="350" Width="525">
<Grid>
<StackPanel Orientation="Vertical">
<local:MyButton x:Name="ButtonA" Height="100" Click="ButtonA_Click"/>
<local:MyButton x:Name="ButtonB" Height="100" Click="ButtonB_Click" />
</StackPanel>
</Grid>
</Window>
3、在SpaceWindow中定义一个依赖属性,并为两个button添加单击事件处理程序:
public partial class SpaceWindow : Window
{
public SpaceWindow()
{
InitializeComponent();
index1 = index2 = 0;
}
private int index1;
private int index2;
private void ButtonA_Click(object sender, RoutedEventArgs e)
{
ButtonA.Space = "ButtonA被点击了。了。。了。。。" + index1.ToString();
index1++;
}
private void ButtonB_Click(object sender, RoutedEventArgs e)
{
Space = "ButtonB被点击了。了。。了。。。"+index2.ToString();
index2++;
}
static SpaceWindow()
{
FrameworkPropertyMetadata md = new FrameworkPropertyMetadata("Hello", WinSpacePropertyChangedCallback);
//FrameworkPropertyMetadata md = new FrameworkPropertyMetadata();
md.Inherits = true;//必须的
SpaceProperty = MyButton.SpaceProperty.AddOwner(typeof(SpaceWindow));
SpaceProperty.OverrideMetadata(typeof(Window), md);
}
public static readonly DependencyProperty SpaceProperty;
public string Space
{
get
{
return (string)GetValue(SpaceProperty);
}
set
{
SetValue(SpaceProperty, value);
}
}
private static void WinSpacePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var str = e.NewValue;
}
}
4、注意
①在SpaceWindow中定义的依赖属性不是通过Register方法来生成的,而是用某个控件(MyButton)的属性的AddOwner方法来完成的:
SpaceProperty = MyButton.SpaceProperty.AddOwner(typeof(SpaceWindow));
实际上他还可以接受一个元数据的参数:
SpaceProperty = MyButton.SpaceProperty.AddOwner(typeof(SpaceWindow), new FrameworkPropertyMetadata("Hello", WinSpacePropertyChangedCallback));
也就是接受一个元数据参数,如果增加了这个元数据,就相当于调用了重载元数据OverrideMetadata函数:
FrameworkPropertyMetadata md = new FrameworkPropertyMetadata("TextB", WinSpacePropertyChangedCallback);
SpaceProperty = MyButton.SpaceProperty.AddOwner(typeof(SpaceWindow));
SpaceProperty.OverrideMetadata(typeof(Window), md);
②
重载元数据也就是新租车的依赖属性有着自己的元数据,如上面的元数据增加了自己的PropertyChangedCallback函数,当属性值被改变的时候就会调用自己回调函数,然后再调用他继承得到的回调函数,如果重载自己的回调函数,那么就只调用继承来的回调函数。
③(重点)
属性值继承的通俗理解就是我将我的(MyButton)Space属性增加一个拥有者(AddOwner方法)SpaceWindow。
**********************特别强调*******************
当MyButton中Space属性中值为默认值时,改变SpaceWindow中Space属性的值时,MyButton中Space属性的值也会改变;但是*,当MyButton中Space属性的值不是默认值时,改变SpaceWindow中Space属性的值就不会影响MyButton中Space属性的值了,这时候他们就分别存储了自己的有效属性值。*但是**当SpaceWindow中Space属性的值改变时,继承得到的PropertyChangedCallback函数依然会调用.
此外,如果MyButton中Space属性的值没有改变,修改了SpaceWindow中Space的值会两次调用MyButton中PropertyChangedCallback函数,因为一次是修改SpaceWindow中Space的值,一次是修改MyButton中Space的值。