WPF依赖属性概述

文章目录

  • 一、前言
  • 二、依赖属性
    • 2.1 前置知识
    • 2.2 依赖属性与CLR属性
    • 2.3 依赖属性支持CLR属性
    • 2.4 设置属性值
      • 2.4.1 在XAML中设置属性值
      • 2.4.2 在代码中设置属性
    • 2.5 依赖属性提供的属性功能
      • 2.5.1 资源
      • 2.5.2 数据绑定
      • 2.5.3 样式
      • 2.5.4 动画
      • 2.5.5 元数据覆盖
      • 2.5.6 属性值继承
      • 2.5.7 WPF设计器集成
    • 2.6 依赖属性值优先级
      • 2.6.1 为什么存在依赖属性优先级?
    • 2.7 学习更多有关依赖属性的内容
  • 三、结尾

一、前言

最近写的博文知识点都比较基础。
因为写项目时总会遇到一些奇怪的问题,于是按我的性子,就会回过去学一遍。
这归根到底还是自己基础太差,兜兜转转半天还得回来补习。
这不,WPF都用了快两年了,又回来学习依赖属性了。

原文地址


二、依赖属性

WPF提供了一组可用于扩展类型属性功能的服务,该服务统称为WPF属性系统。
由WPF属性系统支持的属性称为依赖属性(dependency property)。

本文介绍WPF属性系统和依赖属性的功能,包括如何在XAML和代码中使用现有的依赖属性。
本概述还介绍了依赖属性特有的内容,例如依赖属性元数据、以及如何在自定义类中创建你自己的依赖属性。

2.1 前置知识

假设你已有.NET类型系统和面向对象编程的基本知识。
那么,按照本文中的示例进行操作,有助于理解XAML并了解如何编写WPF应用程序。

2.2 依赖属性与CLR属性

WPF属性通常会公开为标准的.NET属性。

我们一般把.NET中的属性称为CLR属性。这里的WPF属性指依赖属性。

日常使用时,你可能会与这些属性进行交互,但你并不知道它们是作为依赖属性实现的。而熟悉WPF属性系统有助于你更好地去使用这些功能。(从这可以看出来,对外来讲,对使用者来讲,依赖属性其实和CLR属性一样,只是内部实现上有差别)

依赖属性的目的是提供一种方式,基于其他输入值来计算属性值。包括:

  • 系统属性,例如主题或UI。
  • 即时属性确定机制,例如数据绑定和动画、故事板。
  • 多用模板,例如资源和样式。
  • 通过与元素树中的其他元素的父子关系获知的值。

依赖属性嘛,就是有所依赖的属性,依赖的是别的值。通过别的值的更改,来更新计算自己的值。

此外,依赖属性可提供:

  • 独立的验证。
  • 默认值。
  • 监视其他属性更改的回调。
  • 可根据运行时信息强制属性值的系统。

派生类可以通过重写依赖属性的元数据来更改现有属性的某些特征,而不是重写现有属性的实际实现或创建新属性。

在SDK参考文档中,你可以通过该属性的托管参考页上是否存在依赖属性信息段来辨别一个依赖属性。依赖属性信息段包含指向该依赖属性的 DependencyProperty标识符字段的链接。它还包括该属性的元数据选项列表,每个类的覆盖信息以及其他详细信息。

2.3 依赖属性支持CLR属性

依赖属性和WPF属性系统通过提供支持属性的类型来扩展属性功能,以作为使用私有字段支持属性的标准模式的替代方案。该类型的名称是 DependencyProperty 。定义WPF属性系统另一个重要类型是 DependencyObject ,它定义可注册和拥有依赖属性的基类。

以下是一些常用术语:

  • 依赖属性 Dependency property ,这是由DependencyProperty支持的属性。
  • 依赖属性标识符 Dependency property identifier ,它是注册依赖属性时作为返回值获取的 DependencyProperty 实例,然后存储为类的静态成员。许多与WPF属性系统交互的API使用依赖属性标识符作为参数。
  • CLR包装器 CLR “wrapper” ,是属性的get和set实现。这些实现通过在GetValue和SetValue调用中使用依赖属性标识符来做合并。这样,WPF属性系统就为属性提供了支持。

以下示例定义 IsSpinning依赖属性以展示 DependencyProperty 标识符与其支持属性的关系。

public static readonly DependencyProperty IsSpinningProperty = DependencyProperty.Register("IsSpinning", typeof(bool), typeof(MainWindow));public bool IsSpinning
{get => (bool)GetValue(IsSpinningProperty);Set => SetValue(IsSpinningProperty, value);
}

属性的命名规则及其支持的 DependencyProperty 字段非常重要。字段的名称始终是属性的名称,并加上后缀 Property

2.4 设置属性值

在代码中和XAML中都可以设置属性。

attribute和property都有属性的意思,
property是面向对象的范畴,针对对象的属性特征;attribute是编程语言层面的,针对标签的属性特征,即标签中的 “名称-值” 对。为了避免混淆,后文把property直译为属性,attribute保留英文。

2.4.1 在XAML中设置属性值

下面的XAML示例将一个按钮的背景色设置为红色。XAML attribute的字符串值由WPF XAML解析器进行类型转换为WPF类型。在生成的代码中,WPF类型是由 SolidColorBrush 实现的Color。

<Button Content="I am red" Background="Red"/>

XAML支持多种设置属性的语法形式。特定属性使用哪种语法取决于属性使用的值类型以及一些其他因素,例如是否存在类型转换器。

下面的XAML示例展示了使用属性元素语法(property element syntax)来替换上述的attribute语法。XAML将按钮背景设置为图像而不是简单的纯色。嵌套元素代表图像,元素的attribute指定图像源。

<Button Content="I have an image background"><Button.Background><ImageBrush ImageSource="stripes.jpg"/></Button.Background>
</Button>

2.4.2 在代码中设置属性

在代码中设置依赖属性值通常就是调用由包装器公开的 set 实现:

Button myButton = new ();
myButton.Width = 200.0;

获取属性值本质上是调用 get 包装器的实现:

double whatWidth = myButton.Width;

你也可以直接调用属性系统的API GetValue 和 SetValue。直接调用API适用于某些场景,但通常不适用于使用已有的属性。一般来讲,包装器更方便,并且为开发人员工具提供了更好的属性公开。

属性也可以在XAML中设置,然后通过后置代码访问。

2.5 依赖属性提供的属性功能

与由字段支持的属性不同,依赖属性扩展了属性的功能。通常,支持以下功能:

  • 资源 Resources
  • 数据绑定 Data binding
  • 样式 Styles
  • 动画 Animations
  • 元数据重写 Metadata overrides
  • 属性值继承 Property value inheritance
  • WPF设计器继承 WPF Designer integration

2.5.1 资源

可以通过引用一个资源来设置属性值。
资源通常被指定为页面根元素或应用程序的 Resources 属性值,因为这些位置提供了对资源的便捷访问。在该示例中,我们定义了 SolidColorBrush 资源:

<StackPanel.Resources><SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</StackPanel.Resources>

现在资源已被定义,我们可以引用该资源来为 Background 属性提供值:

<Button Background="{DynamicResource MyBrush}" Content="I am gold"/>

在WPF XAML中,你可以使用静态或动态资源引用。该特定资源被称为DynamicResource。动态资源引用只能用于设置依赖属性,因此它是由WPF属性系统专门启用的动态资源引用用法。

注意
资源被视为本地值,这意味着如果你设置了另一个本地值,将会消除资源引用。

2.5.2 数据绑定

依赖属性可以通过数据绑定引用值。数据绑定通过XAML中的特定标记扩展语法或代码中的Binding对象进行工作。使用数据绑定,最终属性值的确定被推迟到运行时,那时会从数据源获取该值。

下面示例通过使用XAML中声明的绑定设置Button的Content属性。该绑定使用继承的数据上下文和XmlDataProvider数据源(未显示)。绑定本身通过XPath指定数据源内的源属性。

<Button Content="{Binding Source={StaticResource TestData}, XPath=test[1]/@text}"/>

注意
资源被视为本地值,这意味着如果你设置了另一个本地值,将会消除资源引用。

依赖属性或DependencyObject类不原生支持INotifyPropertyChanged来通知数据绑定操作的DependencyObject源属性值的更改。

2.5.3 样式

样式和模板是使用依赖属性的有力理由。样式对于设置定义应用程序UI的属性尤其有用。样式通常定义为XAML中的资源。样式与属性系统交互,因为它们通常包含特定属性的"setter",以及根据另一个属性的运行时值更改属性值的"trigger"。

以下示例创建了一个简单样式,该样式将在Resources字典(未显示)内定义。然后该样式将直接应用于按钮的 Style 属性。样式中的 setter 将样式化的按钮的背景属性设置为绿色。

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

2.5.4 动画

依赖属性可被动画化。当应用的动画运行时,动画值的优先级高于任何其他属性值(包括本地值)。

以下示例为Button的Background属性设置动画。技术上来讲,属性元素语法将空白的 SolidColorBrush 设置为背景,并且 SolidColorBrush的Color属性被动画化。

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

2.5.5 元数据覆盖

当你从最初注册依赖属性的类派生时,可以通过覆盖其元数据来更改依赖属性的特定行为。覆盖元数据依赖于 DependencyProperty 标识符,且不需要重新实现该属性。元数据更改由属性系统本地处理。每个类都有可能按类型保存从基类继承的所有属性的独立元数据。

以下示例覆盖DefaultStyleKey依赖属性的元数据。覆盖该特定依赖属性的元数据是创建可以使用主题默认样式的控件的实现模式的一部分。

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

2.5.6 属性值继承

元素可以从对象树中的父元素继承依赖属性的值。

注意
属性值继承行为并未对所有依赖属性全局启用,因为继承需要计算,计算会消耗时间,这会影响性能。
属性值继承通常仅在表明适用性的场景中启用。你可以通过查看SDK参考中该依赖属性的"依赖属性信息"部分来检查该依赖项是否继承。

以下示例展示了一个绑定,其中包含用于指定绑定源的 DataContext 属性。因此,子对象中的绑定不需要指定源,就能从父StackPanel对象中的 DataContext 取得继承值。或者,子对象可以直接在Binding中指定自己的 DataContext或Source ,不使用继承的值。

<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource TestData}}"><Button Content="{Binding XPath=test[2]/@text}"/>
</StackPanel>

2.5.7 WPF设计器集成

具有依赖属性实现的属性的自定义控件与VS的WPF设计器很好地集成。一个例子是能够在 属性 窗口中编辑直接的和附加的依赖属性。

2.6 依赖属性值优先级

WPF属性系统中任何基于属性的输入都可以设置依赖属性的值。依赖属性值优先级的存在,以便在不同场景下,属性获取值以一种可预测的方式进行。

注意
在讨论依赖属性时,SDK文档有时会使用术语 “局部值(local value)” 或 “局部设置值(locally set value)”局部设置值是直接在代码中的对象实例上设置的属性值,或者在XAML中作为元素attribute值

下面示例包含一个应用于任何按钮 Background 属性的样式,但指定了一个具有局部设置 Background 属性的按钮。从技术上讲,该按钮的 Background 属性设置了两次,尽管只会应用一个值——优先级最高的值。局部设置值具有最高优先级,除了运行中的动画外,但此处不存在动画。因此,第二个按钮使用 Background 属性的局部设置值,而不是样式设置器的值。第一个按钮没有局部值或优先级高于样式设置器的其他值,因此使用 Background 属性的样式设置器值。

<StackPanel><StackPanel.Resources><Style x:Key="{x:Type Button}" TargetType="{x:Type Button}"><Setter Property="Background" Value="Orange"/></Style></StackPanel.Resources><Button>I am styled orange</Button><Button Background="Pink">I am locally set to pink(not styled orange)</Button>
</StackPanel>

2.6.1 为什么存在依赖属性优先级?

局部值优先于样式设置器值,后者支持元素属性的局部控制。

注意
WPF元素上定义的许多属性不是依赖属性,因为依赖属性通常仅在需要WPF属性系统的功能时才实现。这些功能包括数据绑定、样式、动画、默认值支持、继承、附加属性和失效。

2.7 学习更多有关依赖属性的内容

  • 组件开发人员或应用程序开发人员可能希望创建自己的依赖属性来添加功能,例如数据绑定或样式支持,或者验证和值强制支持。有关信息,查看 “自定义依赖属性” 章节。
  • 将依赖属性视为公开属性,任何有权访问实例的调用者都可以访问和发现。更多信息,查阅 “依赖属性安全性” 章节。
  • 附加属性是一种XAML中支持专门语法的属性类型。附加属性通常与CLR属性没有1:1对应关系,且不一定是依赖属性。附加属性的主要目的是允许子元素向父元素报告属性值,即使父元素和子元素不包含该属性作为类成员列表的一部分。一种主要场景是使子元素能够通知父元素如何在UI中呈现它们。例如,Dock 和 Left。更多信息,查阅 “附加属性概述” 章节。

三、结尾

写这篇博客其实是源于一个问题,
我重写了一个按钮的样式,主要是控件模板,并且添加了一个触发器(鼠标进入改变背景色)。
我将新样式应用于两个按钮,一个按钮未显式设置Background,另一个按钮设置Background。
结果,未显式设置背景色的按钮,鼠标移入后会变色,另一个则不会。
现在看来,是依赖属性优先级的问题,局部设置值具有最高优先级。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/723059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于GitBucket的Hook构建ES检索PDF等文档全栈方案

背景 之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo&#xff0c;预期建设方案是使用触发器类型从公共的文档源拉取最新的文件&#xff0c;然后调用Java将文件转Base64后入ES建索引&#xff0c;再提供封装接口给前端做查询之用。 由于全部内容过长&#xff…

YOLO算法改进Backbone系列之:RepViT

摘要&#xff1a;近年来&#xff0c;与轻量级卷积神经网络(cnn)相比&#xff0c;轻量级视觉变压器(ViTs)在资源受限的移动设备上表现出了更高的性能和更低的延迟。这种改进通常归功于多头自注意模块&#xff0c;它使模型能够学习全局表示。然而&#xff0c;轻量级vit和轻量级cn…

《操作系统真相还原》读书笔记四:安装nasm

下载链接&#xff1a;https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/ 下载-解压-安装 tar zxvf nasm-2.13.03.tar.gz ./configure --prefix/home/truthos/nasm/toolchain/make && makeinstall执行make install export PATH/home/truthos/nasm/toolchain/bin:…

微信小程序云开发教程——墨刀原型工具入门(编辑页面)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

硬件工程师面经整理20_阻抗匹配

文章目录 阻抗匹配_微波电路/低噪放/差分信号线1 微波电路的匹配电阻2 低噪声运放阻抗匹配3 差分信号线阻抗匹配一般是多少 互连链路阻抗特性 阻抗匹配_微波电路/低噪放/差分信号线 1 微波电路的匹配电阻 微波电路的匹配电阻指的是在微波频段内&#xff0c;由于电路阻抗的不匹…

html标签之表格标签,资料分享

二.准备工作 与中国大部分在校生一样&#xff0c;从不考虑多多参加社会活动为自己铺路&#xff0c;直到找工作时才发现自己一无所有。 是的&#xff0c;一无所有。对于求职来说&#xff0c;如果不找对口工作&#xff0c;那么你的专业知识已经无用武之地。能证明你能力的实践活…

Windows上websocket客户端连接定时存储消息到文件并加载文件定时发送服务端工具实现

场景 在业务开发中&#xff0c;需要对接三方websocket协议数据或者连接并存储线上websocket协议数据&#xff0c;需要使用websocket客户端 连接线上的websocket服务端获取并存储数据&#xff0c;然后将数据存储成文件格式可移植&#xff0c;并将数据复制 到本地&#xff0c;…

MATLAB知识点:while循环的注意事项

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自​第4章&#xff1a;MATLAB程序流程控制 在使用while循…

Linux中basename作用

在Shell脚本中&#xff0c;basename 是一个用于提取文件名或路径的基本名称&#xff08;basename&#xff09;的工具。它通常用于处理文件路径&#xff0c;以获取文件的名称部分或去除路径信息。 basename 命令的语法如下&#xff1a; basename STRING [SUFFIX] 其中&#x…

docker 安装rabbitmq并配置hyperf使用

这里我想完成的是 制作消息&#xff08;多个协程制造&#xff09;——》推送到rabbitmq——》订阅消息队列——》消费消息&#xff08;ws协程客户端【一次消费多条】/ws前端&#xff09; 利用 WebSocket 协议让客户端和服务器端保持有状态的长链接&#xff0c;保存链接上来的客…

Grind 75 | 1. Two Sum | 2. valid parentheses

来刷刷Grind 75, Blind 75作者更新版. Leetcode1 两数之和 经典题 link 思路&#xff1a; 很明显用hash table&#xff0c;一开始思考遍历2遍数组&#xff0c;第一遍加入hash table中&#xff0c; 第二遍对每个元素看能不能找到sum target&#xff0c;但思考如果有重复元素…

阿里云2核4G服务器支持多少人同时在线?

2核4G服务器支持多少人在线&#xff1f;阿里云服务器网账号下的2核4G服务器支持20人同时在线访问&#xff0c;然而应用不同、类型不同、程序效率不同实际并发数也不同&#xff0c;2核4G服务器的在线访问人数取决于多个变量因素&#xff1a; 2核4G&#xff1a;2核CPU和4G内存对…

学习笔记-cmake

cmake的版本号说明&#xff1a; CMAKE_MINIMUM_REQUIRED(VERSION 3.10) # 指定编译 C 版本 set(CMAKE_CXX_STANDARD 17) 创建一个工程&#xff1a; project(preprocess) 工程下创建一个项目&#xff1a; SET(PROGRAM WorkStation) include路径&#xff1a; set (INCLUD…

Nginx原理以及基础知识详解

Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;具有高并发性、高可靠性、低内存消耗等特点。其工作原理和基础知识如下&#xff1a; 一、Nginx的工作原理 Nginx采用多进程模型&#xff0c;主进程负责接收客户端的连接请求&#xff0c;然后将连接请求分发给工作进程来处…

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记02_大数据

1. 大数据分析 1.1. 随着“大数据军备竞赛”与定价算法的广泛应用&#xff0c;线上购物平台与实体商铺的界限也变得越来越模糊 1.2. 在沃尔玛疯狂扩张的时代&#xff0c;它给地区性商业带来的伤害不亚于一场地震 1.2.1. 当地的小型商铺往往…

浏览器工作原理与Javascript高级(异步)

总体介绍 浏览器运行是多进程的&#xff0c;包括主进程、渲染进行、网络进程和GPU进程等等 解析HTML时(渲染进程)用到两大引擎&#xff0c;一个是渲染引擎&#xff08;用于渲染页面&#xff09;、一个是JS引擎用于解析JS代码。又JS引擎运行是单线程的&#xff0c;所以渲染和 …

Dubbo基础入门一

1、什么是Dubbo3 Apache Dubbo 是一款易用、高性能的 WEB 和 RPC 框架&#xff0c;同时为构建企业级微服务提供服务发现、流量治理、可观测、认证鉴权等能力、工具与最佳实践。 “Dubbo3 已在阿里巴巴内部微服务集群全面落地&#xff0c;成功取代运行多年的 HSF 框架。” 2、…

【Linux】Linux原生异步IO(二):libaio相关结构体、函数详解

1、结构体 1.1 iocb struct iocb成员变量详解: struct iocb {PADDEDptr(void *data, __pad1); /1、在io完成事件中返回,与io_getevents方法返回的io_event结构体data成员一致一般存放用户自定义数据、用户数据、回调函数*/PADDED(unsigned key, aio_rw_flags

5G 网络切片VLAN ID配置错误导致业务不可用

【摘要】随着电联5G共建共享工作的开展&#xff0c;无法及时有效观测到单逻辑站点的相关指标&#xff0c;导致单运营商用户业务出现异常。本案例中着重对单运营商用户无法使用网络进行相关参数排查&#xff0c;从KPI性能指标结合故障告警发生时间&#xff0c;从而分析由于网络切…

稀碎从零算法笔记Day6-LeetCode:长度最小的子数组

前言&#xff1a;做JD的网安笔试题&#xff0c;结果查找子串&#xff08;单词&#xff09;这个操作不会。痛定思痛&#xff0c;决定学习滑动数组 题型&#xff1a;数组、双指针、滑动窗口 链接&#xff1a;209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 来…