zoukankan      html  css  js  c++  java
  • WPF之依赖属性

    简而言之,依赖属性就是一种可以自己没有值,并能通过使用Binding从数据源获得值(依赖在别人身上)的属性。而拥有依赖属性的对象被称为依赖对象

    与传统的CLR属性和面向对象思想相比依赖属性有很多新颖之处:

    • 节省实例对内存的开销。因为属性值在其他对象那里,而不在使用依赖属性的对象这里,所以节省了内存开销。
    • 属性值可以通过Binding依赖在其他对象上。

    依赖属性对内存的使用方式

    传统的.NET开发中,一个对象所占用的内存控件在调用new操作符进行实例化的时候就已经决定了,而WPF允许对象在被创建的时候并不包含用于储存数据的控件,只保留在需要时候能够获得默认值,借用其他对象数据或者分配空间的能力,这种对象就称为依赖对象,而它这种实时获取数据的能力则依靠依赖属性来实现,注意依赖对象不是数据产生的对象,而是具备获取其他对象的数据的能力的对象。

    需要注意的是ItemSource所绑定的属性,必须同时具备{get;set;},如果不允许用户修改,则{get;private set},但必须同时具备,否则绑定的UI元素不会显示名称.

    在WPF中,依赖对象的概念被DependencyObject类所实现,依赖属性的概念被DependencyProperty类所实现。DependencyObject具有GetValue和SetValue两个方法,DependencyProperty必须以DependencyObject为宿主,以这两个方法来进行写入与读取。

    public class DependencyOobject:DispatcherObject{
        public object GetValue(DependencyPropertyy dp)//从DependencyProperty对象获取数据
        {
            ...///
        }
        public void SetValue(DependencyProperty dp,object value)
        {
            ...///
        }
    }
    

    DependencyObject是WPF系统中相当底层的一个基类,所有UI控件都是依赖对象。

    例子:

        <StackPanel Background="LightBlue">
            <TextBox x:Name="textBox1" BorderBrush="Black" Margin="5"/>
            <TextBox x:Name="textBox2" BorderBrush="Black" Margin="5"/>
            <Button x:Name="btn" Content="OK" Click="btn_Click"/>
        </StackPanel>
    
        public partial class MainWindow : Window
        {
            Student stu;
            public MainWindow()
            {
                InitializeComponent();
                stu = new Student();
                Binding binding = new Binding("Text") { Source = this.textBox1 };
                stu.SetBinding(Student.NameProperty, binding);
                textBox2.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = stu });
            }
    
            private void btn_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show(stu.Name);
            }
        }
        public class Student : DependencyObject
        {
            //注册依赖属性
            public static readonly DependencyProperty NameProperty =
                DependencyProperty.Register("Name", typeof(string), typeof(Student));
            //CLR包装属性
            public string Name
            {
                get { return (string)GetValue(NameProperty); }
                set { SetValue(NameProperty, value); }
            }
            //SetBinding包装
            public BindingExpressionBase SetBinding(DependencyProperty dp,BindingBase binding)
            {
                return BindingOperations.SetBinding(this, dp, binding);
            }
    
        }
    

    image-20211114204437950

    简单总结下创建依赖对象,使用依赖属性的三部曲:

    • 继承DependancyObject

    • 在依赖对象内用DependancyProperty.Register方法注册依赖属性

    • 用CLR属性进行包装,结合依赖对象的SetValueGetValue方法。

    附加属性

    附加属性将的是一个属性本来不属于某个对象,但由于某种需求而被后来附加上。也就是把对象放入一个特定的环境后哦,对象才具有的属性。

    Demo:

        <StackPanel Background="LightBlue">
    
            <Button x:Name="btn" Content="OK" Click="btn_Click"/>
        </StackPanel>
    
    namespace MessagePump
    {
    
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
            }
    
            private void btn_Click(object sender, RoutedEventArgs e)
            {
                Human human = new Human();
                School.SetGrade(human, 6);
                int grade = School.GetGrade(human);
                MessageBox.Show(grade.ToString());
            }
        }
        public class School : DependencyObject
        {
            //通过GetGrade、SetGrade,调用Human的SetValue和GetValue方法,存储依赖变量的值。
    
            public static int GetGrade(DependencyObject obj)
            {
                return (int)obj.GetValue(GradeProperty);
            }
    
            public static void SetGrade(DependencyObject obj, int value)
            {
                obj.SetValue(GradeProperty, value);
            }
    
            // Using a DependencyProperty as the backing store for GradeProperty.  This enables animation, styling, binding, etc...(注册依赖变量)
            public static readonly DependencyProperty GradeProperty =
                DependencyProperty.RegisterAttached("Grade", typeof(int), typeof(School), new PropertyMetadata(0));
        }
    
        class Human : DependencyObject
        {
    
        }
    }
    

    image-20211114220702538

    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    scrapy 项目搭建
    linux mysql -- ERROR! The server quit without updating PID file (/usr/local/mysql/data/localhost.localdomain.pid)
    linux 安装python 和pip
    转 Pycharm及python安装详细教程
    mysql在linux下的安装
    easyui datagrid动态修改editor时动态绑定combobox的数据
    easyui combobox 在datagrid中动态加载数据
    linux 安装tomcat
    CUBRID学习笔记23 关键字列表
    CUBRID学习笔记 22 插入数据
  • 原文地址:https://www.cnblogs.com/johnyang/p/15553747.html
Copyright © 2011-2022 走看看