WPF/Silverlight ->DependencyProperty
之前我们所学的属性是这样设计的 [csharp] private Uri url; public Uri Url { get { return url; } set { url = value; } } [/csharp] 由于WPF中的依赖属性非常强大,所以它的属性应该这样设计 [csharp] public static readonly DependencyProperty url = DependencyProperty.Register("Imageurl", typeof(Uri), typeof(Pic), new PropertyMetadata(string.Empty)); public Uri Imageurl { get { return (Uri)GetValue(url); } set { SetValue(url, value); } } [/csharp] 除了写法复杂点,它的优势在哪里呢?首先,PropertyMetadata方法给属性了一个初值(当然在传统的属性设计中也很容易实现), 我们先看它的构造函数 [csharp] <pre>public PropertyMetadata(object defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);</pre> [/csharp] 第一个给属性的默认值,第二个是一个回调函数,当属性的值改变时,就会调用这里面的函数,第三个还是一个回调函数,这个函数主要用来强制一个值,比如该属性的值必须在0-100之间,那么当给该属性赋值1000时,需要做相应的处理,就在这里。
Register还有一个参数ValidateValueCallback,它也是一个回调函数,
是该属性的“大门”,用来指示该属性是否有效,
返回值为bool类型,如果它设置为无效,
那么值改变,强制值的那些回调函数都不会执行。
总的来说,比传统的方法更强大,属性一旦定义好,就能够保证数据的正确。
下面来个完整的例子
[csharp]
class Program
{
static void Main(string[] args)
{
SimpleDpClass sim = new SimpleDpClass();
sim.SimpleDP = 8;
}
}
public class SimpleDpClass : DependencyObject
{
public static readonly DependencyProperty SimpleDpProperty = DependencyProperty.Register("SimpleDP", typeof(double), typeof(SimpleDpClass),
new FrameworkPropertyMetadata((double)0.0,
FrameworkPropertyMetadataOptions.None,
new PropertyChangedCallback(OnValueChange),
new CoerceValueCallback(CoerceValue)),
new ValidateValueCallback(IsValidValue));
public double SimpleDP
{
get{return (double)GetValue(SimpleDpProperty);}
set{SetValue(SimpleDpProperty,value);}
}
private static void OnValueChange(DependencyObject obj,DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("当值改变时,需要做一些操作,就在这里{0}",e.NewValue);
}
private static object CoerceValue(DependencyObject obj,object value)
{
double myvalue=0;
if ((double)value > 5)
{
myvalue = 10;
}
Console.WriteLine("对值进行限定,强制值: {0}", myvalue);
return myvalue;
}
private static bool IsValidValue(object value)
{
Console.WriteLine("验证值是否通过,返回bool值,如果返回True表示严重通过,否则会以异常的形式暴露: {0}", value);
return true;
}
}
[/csharp]
接下来了解下监听属性
在这里,继承自DependencyObject的所有对象的属性都能够监听,有2种方法
- 继承自你要监听属性的类,重写元数据,比如我想监听TextBox的Background属性,那么[csharp] <pre>public class MyTextBox : TextBox { public MyTextBox():base() { } static MyTextBox() { BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(bkCallback))); } private static void bkCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { MessageBox.Show("改变了颜色"); } }</pre> [/csharp] 这样就监听了背景颜色
- 用于某一个控件[csharp] <pre>public MainWindow() { InitializeComponent(); DependencyPropertyDescriptor des = DependencyPropertyDescriptor.FromProperty(Button.BackgroundProperty, typeof(Button)); des.AddValueChanged(mybutton, new EventHandler(buttonbkchange)); } private void buttonbkchange(object sender, EventArgs e) { MessageBox.Show("Button BackgroundChange"); }</pre> [/csharp]
- 完整的例子[csharp] <pre>public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DependencyPropertyDescriptor des = DependencyPropertyDescriptor.FromProperty(Button.BackgroundProperty, typeof(Button)); des.AddValueChanged(mybutton, new EventHandler(buttonbkchange)); } private void buttonbkchange(object sender, EventArgs e) { MessageBox.Show("Button BackgroundChange"); } private void Button_Click(object sender, RoutedEventArgs e) { mybutton.Background = Brushes.Blue; myTextBox.Background = Brushes.Green; } } public class MyTextBox : TextBox { public MyTextBox():base() { } static MyTextBox() { BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(bkCallback))); } private static void bkCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { MessageBox.Show("改变了颜色"); } }</pre> [/csharp] 有关WPF属性的基本介绍就到这里,有更加详细的资料在这儿http://www.cnblogs.com/KnightsWarrior/archive/2010/08/27/1809739.html

浙公网安备 33010602011771号