什么是依赖附加属性

依赖属性就是一种自己可以没有值,并且可以通过绑定从其他数据源获取值。依赖属性可支持WPF中的样式设置、数据绑定、继承、动画及默认值。

如果要定义依赖属性,必须满足下面三个条件:

1 所属对象必须是依赖对象(依赖对象就是说必须要继承自DependencyObject,在wpf中大部分)

2 必须是静态+readonly

3 不是通过new而是通过注册来完成定义的

下面展示一个简单的依赖属性定义:

   public partial class MyDependency : UserControl
    {
        public MyDependency()
        {
            InitializeComponent();
        }
         
        public int MyProperty
        {
            get { return (int)GetValue(MyPropertyProperty); }
            set { SetValue(MyPropertyProperty, value); }
        }

        /// <summary>
        /// 定义一个依赖属性,不是通过new生成,而是通过n注册生成的,
        /// 注意第一个参数之所以是MyProperty是因为依赖属性默认后面是Property来结尾,是默认的一个约束,
        /// 
        /// </summary>
        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.Register("MyProperty", typeof(int), typeof(MyDependency), new PropertyMetadata(0));
         

    }

 

至于依赖附加属性,看下面一个这个例子:

<UserControl x:Class="MyWpf.MyGrid"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyWpf"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <!--指定宽高,剩余的会自动占满-->
            <RowDefinition Height="90"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <!--可以指定行列-->
        <Border Background="Red" Grid.Row="0"></Border>
        <Border Background="Blue" Grid.Row="1"></Border>
        <Border Background="SandyBrown" Grid.Column="1" Grid.Row="0"></Border>
        <Border Background="RosyBrown" Grid.Column="1" Grid.Row="1"></Border>
    </Grid> 
</UserControl>

 

<Border>标签这是没有Row这个属性的,但是通过Grid中的这个属性附加到了Border上,使得Border标签也有了Row属性。使用附加属性,属性定义在与其使用的类不同的类上。这通常用于布局。

依赖附加属性关心的不是拥有者是不是依赖对象,关心的是被附加的对象。

定义一个依赖附加属性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyWpf
{
    /// <summary>
    /// MyDependency.xaml 的交互逻辑
    /// </summary>
    public partial class MyDependency : UserControl
    {
        public MyDependency()
        {
            InitializeComponent();
        } 

        /// <summary>
        /// 定义一个依赖属性,不是通过new生成,而是通过n注册生成的,
        /// 注意第一个参数之所以是MyProperty是因为依赖属性默认后面是Property,
        /// 
        /// </summary>
        public static readonly DependencyProperty MyTestProperty =
            DependencyProperty.RegisterAttached("MyTest", typeof(int), typeof(MyDependency), new PropertyMetadata(0));
        /// <summary>
        /// 注意必须是Get+附加属性的名称,默认的后缀Property不用写在这里
        /// </summary>
        /// <param name="dependency"></param>
        /// <returns></returns>
        public string GetMyTest(DependencyObject dependency)
        {
            return (string)dependency.GetValue(MyTestProperty);
        }

        public void SetMyTest(DependencyObject dependency,string value)
        {
            dependency.SetValue(MyTestProperty,value);
        } 
    } 

}

 

依赖属性和依赖附加属性的区别

 1 承载对象的区别

一个是需要拥有者必须是依赖对象,依赖附加属性则要求被附加对象是依赖对象

2 定义方法的区别

一个是Regist,一个是RegisterAttached

3 包装(封装)

 依赖属性使用属性包装器,但是依赖附加属性使用的是方法包装

 

依赖附加属性使用场景

 1 绑定中转