zoukankan      html  css  js  c++  java
  • (4) C# 依赖项属性

      把对象赋值给属性

     一、依赖属性

    1.定义依赖属性

    一般情况下只是使用,但如果要自定义WPF控件或者给现有的WPF控件增加新功能时就需要自定义。

    定义时需要用到特殊的语法:

    • 静态的
    • 使用readonly只能在构造时初始化
    • 必须是DependencyProperty类实例
    • 属性名称后面要带上Property

    定义一个Margin依赖项属性的例子

    public static readonly DependencyProperty MarginProperty;

    2.注册依赖属性

    (1)创建FrameworkPropertyMetadata对象,指明通过依赖项属性使用什么服务(支持数据绑定,动画,日志等)

    FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(new Thickness(), FrameworkPropertyMetadataOptions.AffectsMeasure);

    (2)调用DependencyProperty.Register()静态方法注册属性 

    五个参数

    • 属性名
    • 属性使用的数据类型
    • 拥有该属性的类型
    • 具有附加属性设置的FrameworkPropertyMetadata对象(此参数可选)
    • 用于验证属性的回调函数(此参数可选)

    在构造函数中

    MarginProperty = DependencyProperty.Register("Margin", typeof(Thickness), typeof(FrameworkElement), metadata, new ValidateValueCallback(FrameworkElement.IsMarginValid));

    3.封装WPF依赖属性

    使用DependencyObject类的SetValue()和GetValue()方法

            public Thickness Margin
            {
                set { SetValue(MarginProperty, value); }
                get { return (Thickness)GetValue(MarginProperty); }
            }

    设置属性

    element.Margin = new Thickness(5);

    4.例子

    一个按钮继承关系 Button--》ButtonBase--》ContentControl--》Control--》FrameworkElement--》UIElement--》Visual--》DependencyObject--》DispatcherObject--》Object

    其中

    • ButtonBase 表示所有 Button 控件的基类,在System.Windows.Controls.Primitives命名空间下(和winfrom下的ButtonBase虽然名字相同,但完全是两条不同的路线)
    • ContentControl  表示包含一段任意类型内容的控件
    • Control 表示用户界面 (UI) 元素的基类,这些元素使用 ControlTemplate 来定义其外观
    • FrameworkElement 提供 WPF元素的属性、事件和方法的 WPF 框架级别集
    • UIElement 是 WPF 核心级实现的基类,这些实现是在 WPF元素和基本表示特性上生成的
    • Visual 为 WPF 中的呈现提供支持,其中包括命中测试、坐标转换和边界框计算
    • DependencyObject 表示参与依赖属性系统的对象,如果设置依赖属性直接继承此类即可

    完整代码:自定义FrameworkElement类

        class FrameworkElement:UIElement
        {
            public static readonly DependencyProperty MarginProperty;
            
            static FrameworkElement()
            {
                FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(new Thickness(), FrameworkPropertyMetadataOptions.AffectsMeasure);
                MarginProperty = DependencyProperty.Register("Margin", typeof(Thickness), typeof(FrameworkElement), metadata, new ValidateValueCallback(FrameworkElement.IsMarginValid));
            }
    
            private static bool IsMarginValid(object value)
            {
                throw new NotImplementedException();
            }
    
            public Thickness Margin
            {
                set { SetValue(MarginProperty, value); }
                get { return (Thickness)GetValue(MarginProperty); }
            }
        }

    去掉ValidateValueCallback参数

    使用

                FrameworkElement element = new FrameworkElement();
                element.Margin = new Thickness(5);

    4.依赖属性变更通知

    有两种方式通知依赖属性变化 --后补

    (1)属性值创建绑定

    (2)编写能够自动改变其他属性或开始动画的触发器

    5.共享依赖属性

    查看TextBlock源码,没有用DependencyProperty.Register注册,而是使用了TextElement的FontFamilyProperty的依赖属性

    FontFamilyProperty = TextElement.FontFamilyProperty.AddOwner(typeof(TextBlock));

    6.附加依赖属性

    附加属性被应用的类不是定义附加属性的那个类,

    比如  DockPanel 的DockProperty属性

    [CommonDependencyProperty]
    public static readonly DependencyProperty DockProperty;
          
    static DockPanel()
    {
      DockProperty = DependencyProperty.RegisterAttached("Dock", typeof(Dock), typeof(DockPanel), new FrameworkPropertyMetadata(Dock.Left, OnDockChanged), IsValidDock);       
    }

    DockPanel.Dock 属性作用到了Border上

        <DockPanel LastChildFill="True">
            <Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
                <TextBlock Foreground="Black">Dock = "Top"</TextBlock>
            </Border>
            <Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
                <TextBlock Foreground="Black">Dock = "Top"</TextBlock>
            </Border>
            <Border Height="25" Background="LemonChiffon" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom">
                <TextBlock Foreground="Black">Dock = "Bottom"</TextBlock>
            </Border>
            <Border Width="200" Background="PaleGreen" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
                <TextBlock Foreground="Black">Dock = "Left"</TextBlock>
            </Border>
            <Border Background="White" BorderBrush="Black" BorderThickness="1">
                <TextBlock Foreground="Black">This content will "Fill" the remaining space</TextBlock>
            </Border>
        </DockPanel>

     附加属性不需要进行属性封装,可以用于任何依赖对象

    二、属性验证

    1.验证回调

    2.强制回调

  • 相关阅读:
    如何把phpStorm打造成自己的专属IDE?
    PHP伪造referer突破网盘禁止外链(附115源码)
    PHP实现删除非站内外部链接实例代码
    Http Referer的一些总结
    jquery 选择器(name,属性,元素)大全
    Invoke 和 BeginInvoke 的真正涵义
    C# HashSet集合类型使用介绍
    Dev系列控件的AJAX使用Demo
    如何进行SVN数据迁移并保存版本号数据
    Window及document对象
  • 原文地址:https://www.cnblogs.com/buchizaodian/p/11396683.html
Copyright © 2011-2022 走看看