依赖属性如何节约内存
MSDN中给出了下面几种应用依赖属性的场景:
-
希望可在样式中设置属性。
-
希望属性支持数据绑定。
-
希望可使用动态资源引用设置属性。
-
希望从元素树中的父元素自动继承属性值。
-
希望属性可进行动画处理。
-
希望属性系统在属性系统、环境或用户执行的操作或者读取并使用样式更改了属性以前的值时报告。
-
希望使用已建立的、WPF 进程也使用的元数据约定,例如报告更改属性值时是否要求布局系统重新编写元素的可视化对象。
自定义依赖属性
1、声明依赖属性变量。依赖属性的声明都是通过public static来公开一个静态变量,变量的类型必须是DependencyProperty
2、在属性系统中进行注册。
使用DependencyProperty.Register方法来注册依赖属性,
或者是使用DependencyProperty.RegisterReadOnly方法来注册
3、使用.NET属性包装依赖属性
》》》在类型的静态构造函数中通过Register注册 静态 静态 静态
public partial class UserControl1 : UserControl
{
//1、声明依赖属性变量
public static readonly DependencyProperty MyColorProperty;
//2、在属性系统中进行注册
static UserControl1()
{
MyColorProperty = DependencyProperty.Register("MyColor", typeof(string), typeof(UserControl1), new PropertyMetadata("Red",
(s, e) => {
var mdp = s as UserControl1;
if (mdp != null)
{
try
{
var color = (Color)ColorConverter.ConvertFromString(e.NewValue.ToString());
mdp.Foreground= new SolidColorBrush(color);
}
catch (Exception)
{
mdp.Foreground = new SolidColorBrush(Colors.Yellow);
}
}
}));
}
//3、使用.NET属性包装依赖属性:属性名称与注册时候的名称必须一致,
public string MyColor
{
get { return (string)GetValue(MyColorProperty); }
set { SetValue(MyColorProperty, value); }
}
}
依赖属性的优先级
只读依赖属性
附件属性
IsAttached就是一个附加属性,附加属性没有采用CLR属性进行封装,而是使用静态SetIsAttached方法和GetIsAttached方法来存取IsAttached值。这两个静态方法内部一样是调用SetValue和GetValue来对附加属性读写的。
依赖属性的监听
1.使用DependencyPropertyDescriptor类
2.使用OverrideMetadata的方式。
public class MyTextBox : TextBox
{
public MyTextBox()
: base()
{
}
static MyTextBox()
{
//第一种方法,通过OverrideMetadata
TextProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(TextPropertyChanged)));
}
private static void TextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
MessageBox.Show("", "Changed");
}
}
public MainWindow()
{
InitializeComponent();
//第二种方法,通过OverrideMetadata
DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
descriptor.AddValueChanged(tbxEditMe, tbxEditMe_TextChanged);
}
private void tbxEditMe_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("", "Changed");
}
附件属性应用 旋转
public class ManagerRotate:DependencyObject {
public static double GetAngle(DependencyObject obj)
{
return (double)obj.GetValue(AngleProperty);
}
public static void SetAngle(DependencyObject obj, double value)
{
obj.SetValue(AngleProperty, value);
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AngleProperty =
DependencyProperty.RegisterAttached("Angle", typeof(double), typeof(ManagerRotate), new PropertyMetadata(0.0,OnAngleChanged));
private static void OnAngleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as UIElement;
if (element != null)
{
element.RenderTransformOrigin=new Point(0.5,0.5);
element.RenderTransform = new RotateTransform((double)e.NewValue);
}
}
}