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


    只有依赖属性,附件属性是特殊的依赖属性,才能绑定。

    依赖属性如何节约内存

    在这里插入图片描述
    在这里插入图片描述

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

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

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

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

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

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

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

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

    自定义依赖属性

    1、声明依赖属性变量。依赖属性的声明都是通过public static来公开一个静态变量,变量的类型必须是DependencyProperty
    2、在属性系统中进行注册。
    使用DependencyProperty.Register方法来注册依赖属性,
    或者是使用DependencyProperty.RegisterReadOnly方法来注册
    3、使用.NET属性包装依赖属性

    在这里插入图片描述
    在这里插入图片描述

    》》 回调顺序》》

    当对依赖属性进行初始化时,会进入两次校验回调函数(具体是什么引起的还没深究),这个阶段如果校验回调函数返回false,会报异常导致程序终止。

    初始化完成后,对依赖属性进行修改时的顺序为:校验回调函数->强制回调函数->回调函数。

    当校验回调函数返回false时,不会进入强制回调函数和回调函数,程序也不会终止。
    当强制回调函数返回null时,不会进入回调函数。
    在这里插入图片描述

    在这里插入图片描述
    》》》在类型的静态构造函数中通过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);
            }
        }
    }
    

    附加属性 、 依赖属性

    》》依赖属性是通过普通的属性进行包装的;
    》》依赖附加属性是通过方法进行包装的,通过向方法传入DependencyProperty对象从而让这个过程与所从属的类型实例解耦,从而使得依赖附加属性可以在不是依赖属性的对象中定义。

    也就是说,依赖属性关注的是属性所从属的对象自身,而依赖附加属性是关注所附加的对象。

    在这里插入图片描述

  • 相关阅读:
    将map对象转换成vo对象
    java基于springboot的高校图书馆座位预约
    [剑指 Offer 24] 反转链表
    C++快排 ~ 三种实现方法
    JS-Dom转为图片,并放入pdf中进行下载
    多级缓存架构
    Java基于B/S架构,包括PC后台管理端、APP移动端、可视化数据大屏的智慧工地源码
    Numpy数组中d[True]=1的含义
    Vue--router和route的区别
    Java Azure开发 使用已有token字符串创建GraphServiceClient
  • 原文地址:https://blog.csdn.net/u013400314/article/details/139330385