zoukankan      html  css  js  c++  java
  • WPF知识4 依赖属性

    依赖项属性是通过调用 Register 方法(或 RegisterReadOnly)在 WPF 属性系统中注册,并通过 DependencyProperty 标识符字段备份的属性。 依赖项属性只能由 DependencyObject 类型使用,但 DependencyObject 在 WPF 类层次结构中的级别很高,因此,WPF 中的大多数可用类都支持依赖项属性。

    我们大部分时间都会使用依赖属性,依赖项属性提供用来扩展属性功能的功能,这与字段支持的属性相反。 每个这样的功能通常都表示或支持整套 WPF 功能中的特定功能:

    资源

    <DockPanel.Resources>
      <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
    </DockPanel.Resources>
    <Button Background="{DynamicResource MyBrush}" Content="I am gold" />

    数据绑定

    <Button Content="{Binding XPath=Team/@TeamName}"/>

    样式

    <Style x:Key="GreenButtonStyle">
      <Setter Property="Control.Background" Value="Green"/>
    </Style>
    <Button Style="{StaticResource GreenButtonStyle}">I am green!</Button>

    动画

    <Button>I am animated
      <Button.Background>
        <SolidColorBrush x:Name="AnimBrush"/>
      </Button.Background>
      <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Loaded">
          <BeginStoryboard>
            <Storyboard>
              <ColorAnimation
                Storyboard.TargetName="AnimBrush" 
                Storyboard.TargetProperty="(SolidColorBrush.Color)"
                From="Red" To="Green" Duration="0:0:5" 
                AutoReverse="True" RepeatBehavior="Forever" />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Button.Triggers>
    </Button>

    元数据重写

    public class SpinnerControl : ItemsControl
    {
        static SpinnerControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(SpinnerControl), 
                new FrameworkPropertyMetadata(typeof(SpinnerControl))
            );
        }
    }

    属性值继承

    <StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource XmlTeamsSource}}">
      <Button Content="{Binding XPath=Team/@TeamName}"/>
    </StackPanel>

    button的content属性值继承了stackpanel的datacontext源


    虽然我们大部分时间都是使用依赖属性来做以上事情,仍然很多时候我们要创建自己的依赖属性,显然,自定义的WPF的控件库,及时不需要动画,数据绑定功能时候我们仍然需要创建自己的依赖属性。创建依赖属性很特殊和普通的.NET属性创建完全不同。

    需要声明的是:只能为依赖对象添加依赖属性(继承自)DependencyObject,WPF基础结构大部分都继承自这个类。

    自定义依赖项属性

    首先,属性所在的类要直接或间接继承DependencyObject。这个类生成的对象表示一个具有依赖项属性的对象,这些对象,都能享用WPF的属性系统(属性系统主要是计算属性的值,并提供有关值已更改的系统通知)方面的服务。这个类有两个比较重要的方法,GetValue(返回当前对象依赖项属性的当前有效值)和SetValue(设置依赖项属性的本地值)。

    其实,属性对应的字段必需是公有,静态,只读的,类型为DependencyProperty。即public static readonly DependencyProperty 字段名,同时字段的命名也有规范,属性名+Property,字段在定义时,通过DependencyProperty.Register来实注册属性(只有注册了,才能使用WPF属性系统的服务)。

    Register方法有三种重载,如下:

    名称

    说明

    Register(String, Type, Type)

    使用指定的属性名称、属性类型和属性所在对象的类型。

    Register(String, Type, Type, PropertyMetadata)

    使用指定的属性名称、属性类型、属性所在对象的类型和属性元数据注册依赖项属性。

    Register(String, Type, Type, PropertyMetadata, ValidateValueCallback)

    使用指定的属性名称、属性类型、属性所在对象的类型、属性元数据和属性的值验证回调来注册依赖项属性。

    Register中,各个参数解释如下:

    String:依赖属性的名字(不加Property,即字段的名字);

    Type:属性的类型;

    Type:属性所属对象的类型;

    PropertyMetadata:依赖项对象的属性元数据,是一个PropertyMetadata类型,可能赋初始值。PropertyMetadata有一个object的构造函数;

    ValidateValueCallback:表示用作回调的方法,这个类型是一个委托,用于验证依赖项属性的值的有效性,因为是委托,故它的构造参数为一个方法名。

      下面是2个开源自定义控件库的代码:分别是两种特殊的button

        public class AppBarButton : Button
        {
            public AppBarButton()
            {
                DefaultStyleKey = typeof (AppBarButton);
            }
    
            public static readonly DependencyProperty MetroImageSourceProperty =
                DependencyProperty.Register("MetroImageSource", typeof(Visual), typeof(AppBarButton), new PropertyMetadata(default(Visual)));
    
            public Visual MetroImageSource
            {
                get { return (Visual)GetValue(MetroImageSourceProperty); }
                set { SetValue(MetroImageSourceProperty, value); }
            }
        }
        public class Tile : Button
        {
            public Tile()
            {
                DefaultStyleKey = typeof (Tile);
            }
    
            public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(Tile), new PropertyMetadata(default(string)));
    
            public string Title
            {
                get { return (string)GetValue(TitleProperty); }
                set { SetValue(TitleProperty, value); }
            }
    
            public static readonly DependencyProperty CountProperty = DependencyProperty.Register("Count", typeof(string), typeof(Tile), new PropertyMetadata(default(string)));
    
            public string Count
            {
                get { return (string)GetValue(CountProperty); }
                set { SetValue(CountProperty, value); }
            }
    
            public static readonly DependencyProperty KeepDraggingProperty = DependencyProperty.Register("KeepDragging", typeof(bool), typeof(Tile), new PropertyMetadata(true));
    
            public bool KeepDragging
            {
                get { return (bool)GetValue(KeepDraggingProperty); }
                set { SetValue(KeepDraggingProperty, value); }
            }
            
            public static readonly DependencyProperty TiltFactorProperty =
                DependencyProperty.Register("TiltFactor", typeof(int), typeof(Tile), new PropertyMetadata(5));
    
            public int TiltFactor
            {
                get { return (Int32)GetValue(TiltFactorProperty); }
                set { SetValue(TiltFactorProperty, value); }
            }
        }

    大致如下:

    定义依赖属性并且注册依赖属性,根据约定,定义的依赖属性名称在普通属性末尾加上单词“Property”,完成注册后,添加属性包装器,使用DependencyObject的GetValue方法和SetValue方法。

    创建依赖属性就完成了。


    属性验证

    wpf使用两种方法用于阻止非法值:

    1,ValidateValueCallback 委托:
    原型:
    public delegate bool ValidateValueCallback(
    	Object value
    )
    true ,如果该值验证; false ,如果已提交的值无效。
    例子:
            private static bool ShirtValidateCallback(object value)
            {
                ShirtTypes sh = (ShirtTypes) value;
                return (sh==ShirtTypes.None || sh == ShirtTypes.Bowling || sh == ShirtTypes.Dress || sh == ShirtTypes.Rugby || sh == ShirtTypes.Tee);
    
            }
    2,CoerceValue方法:略

    http://msdn.microsoft.com/zh-cn/library/system.windows.dependencyobject.coercevalue.aspx
  • 相关阅读:
    【POJ 1958】 Strange Towers of Hanoi
    【HNOI 2003】 激光炸弹
    【POJ 3263】 Tallest Cow
    【POJ 2689】 Prime Distance
    【POJ 2777】 Count Color
    【POJ 1995】 Raising Modulo Numbers
    【POJ 1845】 Sumdiv
    6月16日省中集训题解
    【TJOI 2018】数学计算
    【POJ 1275】 Cashier Employment
  • 原文地址:https://www.cnblogs.com/xiepeixing/p/2995540.html
Copyright © 2011-2022 走看看