依赖属性 附加属性 属性 DependencyProperty AttachedProperty Property

依赖属性:一种可以自己没值,并能通过使用Binding从数据源获得值(依赖在别人身上)的属性。

我们做个小例子:将第二个文本框的值依赖到第一个文本框上,即第一个输什么,第二个就显示什么。

先写个简单的XAML页面: 

<Window x:Class="MyDependencyProperty.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="150" Width="200">
    <StackPanel>
        <TextBox x:Name="textBox1" BorderBrush="Black" Margin="5"/>
        <TextBox x:Name="textBox2" BorderBrush="Black" Margin="5"/>
    </StackPanel>
</Window>
  • 然后我们需要写依赖属性,依赖属性永远是用这三个修饰词:public static readonly。
  • 它的声明和实例化,使用DependencyProperty.Register方法产生。
  • 为了使用方便,我们会对依赖属性进行CLR包装。这样,在使用依赖属性的时候,就跟使用一般的CLR属性一样了。
  • SetBinding包装是为了让Person类能够使用绑定方法绑定界面的textBox1的值。

 实现一个有依赖属性的类:

public class Person : DependencyObject
    {
        /// <summary>
        /// CLR属性包装器
        /// </summary>
        public string Name
        {
            get { return (string)GetValue(NameProperty); }
            set { SetValue(NameProperty, value); }
        }

        /// <summary>
        /// 依赖属性
        /// </summary>
        public static readonly DependencyProperty NameProperty =
            DependencyProperty.Register("Name", typeof(string), typeof(Person));

        /// <summary>
        /// SetBinding包装
        /// </summary>
        /// <param name="dp"></param>
        /// <param name="binding"></param>
        /// <returns></returns>
        public BindingExpressionBase SetBinding(DependencyProperty dp, Binding binding)
        {
            return BindingOperations.SetBinding(this, dp, binding);
        }
    }

然后我们使用Binding把Person的对象per关联到textBox1上,在把textBox2关联到Person对象per上,形成Binding链。

依赖属性使用代码如下:

public Window1()
        {
            InitializeComponent();
            Person per = new Person();
            per.SetBinding(Person.NameProperty, new Binding("Text") { Source = textBox1 });
            textBox2.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = per });
        }

运行效果:

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

比如,人有很多属性,当人在学校里时,会有年级这个属性,这属性不必要一直有,是在学校里而给附加上的

Human类:

class Human : DependencyObject
    { 
    }

再来个School类:

class School : DependencyObject
    {
        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 Grade.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GradeProperty =
            DependencyProperty.RegisterAttached("Grade", typeof(int), typeof(School), new UIPropertyMetadata(0));
        
    }

我们可以看出来:

  • GradeProperty就是DependencyProperty类型成员变量。
  • 声明时同样使用public static readonly这三个修饰词。
  • 不同的是注册附加属性使用的方法是:RegisterAttached(),但参数却与Register无异。
  • 还有不同,包装器不同:依赖属性使用CLR属性对GetValue和SetValue两个方法进行包装;附加属性则使用public static void修饰的两个自命名方法包装。

使用附加属性,如在界面点击Grade的按钮是触发:

private void btn_Grade_Click(object sender, RoutedEventArgs e)
        {
            Human human = new Human();
            School.SetGrade(human, 6);
            int grade = School.GetGrade(human);
            MessageBox.Show(grade.ToString());
        }

它的前台界面:

<Grid>
        <Button Content="Grade" Width="120" Height="25" x:Name="btn_Grade" Click="btn_Grade_Click" />
    </Grid>

运行为:

原文地址:https://www.cnblogs.com/zhangyongheng/p/4768398.html