WPF 依赖属性原理、 附加属性

依赖属性如何节约内存

MSDN中给出了下面几种应用依赖属性的场景:

  1. 希望可在样式中设置属性。

  2. 希望属性支持数据绑定。

  3. 希望可使用动态资源引用设置属性。

  4. 希望从元素树中的父元素自动继承属性值。

  5. 希望属性可进行动画处理。

  6. 希望属性系统在属性系统、环境或用户执行的操作或者读取并使用样式更改了属性以前的值时报告。

  7. 希望使用已建立的、WPF 进程也使用的元数据约定,例如报告更改属性值时是否要求布局系统重新编写元素的可视化对象。

自定义依赖属性

1、声明依赖属性变量。依赖属性的声明都是通过public static来公开一个静态变量,变量的类型必须是DependencyProperty

2、在属性系统中进行注册。

使用DependencyProperty.Register方法来注册依赖属性,

或者是使用DependencyProperty.RegisterReadOnly方法来注册

3、使用.NET属性包装依赖属性

》》》在类型的静态构造函数中通过Register注册 静态 静态 静态

csharp 复制代码
 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的方式。

csharp 复制代码
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");
        }
    }
csharp 复制代码
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");
        }
附件属性应用 旋转


csharp 复制代码
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);
        }
    }
}
相关推荐
张人玉11 小时前
Prism Template Pack 完整使用示例(VS2022 + .NET 8 + DryIoc)
.net·wpf·prism
j***630813 小时前
四大.NET ORM框架深度对比:EF Core、SqlSugar、FreeSql与Dapper的性能、功能与适用场景
.net
我是唐青枫1 天前
C#.NET 范围与索引(Range、Index)完全解析:语法、用法与最佳实践
c#·.net
深海潜水员2 天前
【MonoGame游戏开发】| 牧场物语实现 第一卷 : 农场基础实现 (下)
vscode·游戏·c#·.net·monogame
时光追逐者2 天前
Visual Studio 2026 现已正式发布,更快、更智能!
ide·c#·.net·visual studio
用户7227868123443 天前
.NET 实现雪花算法:高效生成分布式唯一 ID
.net
玩泥巴的4 天前
.NET 8+ 飞书API实战:自动化群组管理与消息推送
c#·.net·二次开发·飞书
唐青枫4 天前
C#.NET 范围与索引(Range、Index)完全解析:语法、用法与最佳实践
c#·.net
许泽宇的技术分享4 天前
当AI Agent遇上.NET:微软Agent Framework的架构奥秘与实战启示
人工智能·microsoft·.net