• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

(4)C#依赖项属性

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  把对象赋值给属性

 一、依赖属性

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.强制回调

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#中静态方法的运用和字符串的常用方法(seventhday)发布时间:2022-07-10
下一篇:
C#无法加载DLL找不到指定的模块(转)发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap