首页 > 其他分享 >.NET|--WPF|--笔记合集|--依赖项属性|--4.依赖项属性值优先级

.NET|--WPF|--笔记合集|--依赖项属性|--4.依赖项属性值优先级

时间:2024-08-31 10:47:47浏览次数:9  
标签:依赖 优先级 -- 样式 设置 属性

前言


前几篇笔记讲到了依赖项属性的定义,注册等.
接下来就该是依赖项属性的实战了.

如果依赖项属性是一个主机的话,
前几个步骤还在于组装这个主机, 组装好了之后, 就要开始使用了, 
是骡子是马, 拉出来遛遛.

但是一般任何事物在使用之前, 都有一些注意事项, 
如果不了解这些注意事项, 就会导致在使用的过程中, 
出现自己无法控制的情况.

比如, 我想给TextBlock的Text属性设置一个值, 但是最终发现, 
我的值也设置了, 但是冠张戴李了, 我设置的是一个"张", 结果最终显示的是"李".

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


还不是为了性能...

依赖项属性优先级

ccc2cc8be8ca275cd2c974837cb843b9.png


对比了从官网中和<<WPF编程宝典>>中, 依赖项属性的优先级, 
会发现, <<WPF编程宝典>>明显的偷工减料.

关键是样式那里, 只有一个来自主题样式和来自项目样式,
我刚开始还有点懵逼, <<WPF编程宝典>>的"2.来自项目样式的值"这一等级,
应该对应官网中的哪一个等级?

对应"5.隐式样式", 还是"6.样式触发器", 还是"7.模板触发器",,,

最终我觉得, 不管官网的[5,6,7,8]反正都是项目中设置的, 
所以我就直接让<<WPF编程宝典>>中的"2.来自项目样式的值"对应官网中的等级[5,6,7,8]了...

官方文档

下面列出了在将运行时值分配给依赖属性时,属性系统所使用的最终优先级顺序。 最高优先级最先列出。

1. 属性系统强制
有关强制转换的详细信息,请参阅强制转换和动画

2. 活动动画或具有 Hold 行为的动画。
若要拥有实用效果,动画必须拥有比基值(无动画)更高的优先级,即使基值进行了本地设置也是如此。 有关详细信息,请参阅强制转换和动画

3. 本地值。
可以通过“包装器”属性设置本地值,这相当于在 XAML 中设置特性或属性元素,或者使用特定实例的属性调用 SetValue API。 通过绑定或资源设置的本地值会具有与直接设置的值相同的优先级。

4. TemplatedParent 模板属性值
如果元素是通过模板创建(ControlTemplateDataTemplate)创建的,则具有 TemplatedParent。 有关详细信息,请参阅 TemplatedParent。 在通过 TemplatedParent 指定的模板中,优先级顺序为:

  1. 触发器。

  2. 属性集(通常通过 XAML 特性进行设置)。

5. 隐式样式
仅应用于 Style 属性。 Style 值是具有与元素类型匹配的 TargetType 值的任何样式资源。 样式资源必须存在于页面或应用程序中。 对隐式样式资源的查找不会扩展到主题中的样式资源。

6. 样式触发器
样式触发器是显式或隐式样式中的触发器。 样式必须存在于页面或应用程序中。 默认样式中的触发器的优先级较低。

7. 模板触发器
模板触发器是直接应用的模板或样式中的模板中的触发器。 样式必须存在于页面或应用程序中。

8. 样式资源库值
样式资源库值是样式中通过 Setter 应用的值。 样式必须存在于页面或应用程序中。

9. 默认样式,也称为主题样式
有关详细信息,请参阅默认(主题)样式。 在默认样式中,优先级顺序如下:

  1. 活动触发器。

  2. 资源库。

10. 继承
子元素的某些依赖属性从父元素继承其值。 因此,可能不需要在整个应用程序中对每个元素设置属性值。 有关详细信息,请参阅属性值继承

11. 依赖属性元数据中的默认值
依赖属性可以在该属性的属性系统注册期间设置默认值。
继承依赖属性的派生类可以选择按照类型重写依赖属性元数据(包括默认值)。
有关详细信息,请参阅依赖属性元数据
对于继承的属性,父元素的默认值优先于子元素的默认值。
因此,如果未设置可继承属性,则会使用根或父级的默认值,而不是子元素的默认值。

<<WPF编程宝典>>
# 我觉得这句话很好"依赖项属性因该行为的命,依赖项属性依赖于多个属性提供者",要把这句话加到前言那篇笔记中去!

依赖项属性因该行为得名,本质上,依赖项属性依赖于多个属性提供者,每个提供者都有各自的优先级。
当从属性检索值时,WPF属性系统会通过一系列步骤获取最终值。
首先通过考虑以下因素(按优先级从低到高的顺序排列)来决定基本值(base value):

(1)默认值
(由 FrameworkPropertyMetadata 对象设置的值)。
(2)继承而来的值
(假设设置了 FrameworkPropertyMetadata.Inherits 标志,并为包含层次中的某个元素提供了值)。
(3)来自主题样式的值
(将在第18 章讨论)。
(4)来自项目样式的值
(将在第 11 章讨论)。
(5)本地值
(使用代码或XAMI 直接为对象设置的值)。

如上面的列表所示,可通过直接应用一个值来覆盖整个层次。
如果不这么做,属性值可由上面列表中的下一个可用项确定。

示例.属性系统强制 和 元数据默认值 和 本地值

可以再回想一下, 依赖属性注册, 注册时候有一个属性元数据参数"System.Windows.FrameworkPropertyMetadata",
而属性元数据实例化的时候, 又有一个可选参数"CoerceValueCallback"

所以, "依赖项属性注册"和"依赖项属性优先级",以及"依赖项属性回调"都是有关系的.
这也是学习过程中需要自己梳理的线, 
场景:
比如人的年龄设置, 普通人的年龄, 都是大于0和小于999的,
这个时候就可以设置, 通过属性系统强制, 可以强行设置一下人年龄的上限和下限.

源码解析--


为什么是个很危险的问题, 
现在知道这种优先级了, 编码中其实大部分情况就可以应对了,
但是如果这时候, 脑袋中突然想, 为什么会这样优先级, 怎么实现的? 
这就需要扒拉源码了...


# 线程校验

return this.Thread == Thread.CurrentThread;

System.Windows.DependencyObject

internal EffectiveValueEntry[] EffectiveValues
{
    [FriendAccessAllowed]
    get
    {
        return this._effectiveValues;
    }
}

System.Windows.Controls.UIElementCollection

        // Token: 0x06007751 RID: 30545 RVA: 0x009A9E3C File Offset: 0x009A9E3C
        protected void SetLogicalParent(UIElement element)
        {
            if (this._logicalParent != null)
            {
                this._logicalParent.AddLogicalChild(element);
            }
        }

插曲--发现巨硬中文官方文档上一个错别字

巨硬中文文档上写错字了,
"回调"写成"回叫"了...哈哈...
207b020db82ad710906b91af9e64a2c2.png

小细节--发现问题,就多打印一些细节...


在搞那个继承值的时候, 一直继承不上, 
就想到想要继承的条件 : 设置了 FrameworkPropertyMetadata.Inherits 标志,并为包含层次中的某个元素提供了值

↓↓↓就把这2个条件打印出来↓↓↓


// 打印出StackPanel的元数据, 主要看"Inherits"是否为"true"
CustomButton.BackgroundColorProperty.GetMetadata(typeof(System.Windows.Controls.StackPanel)).Dump("父节点StackPanel的元数据");

// 父节点StackPanel的值
parentPanel.GetValue(CustomButton.BackgroundColorProperty).Dump("父节点StackPanel的值");
		
// 子节点CustomButton的值
buttonWithInheritedValue.BackgroundColor.Dump("子节点CustomButton的值");


结尾


笔记, 笔记, 自己写的话, 废话可以多一些, 
毕竟整理笔记的时候, 思维确实很容易发散,
杂七杂八的想太多, 

但是如果笔记是想给别人看, 
字的数量还是尽可能少, 
示例和图片可以多一些...
( 我为了画一个好看的金字塔图形, 折腾了好大一会, 还是失败了嘛... 没有艺术细胞... )


我源码都贴上去了, 直接下载一个LINQPad, 都不用打开Visual Studio,
把源码复制进去, 自己改着改着, 调试着调试着, 再看看源码, 就知道咋回事了...

标签:依赖,优先级,--,样式,设置,属性
From: https://www.cnblogs.com/love-zf/p/18389974

相关文章

  • 8.4linux定时任务-环境变量-数据库
    配合SUID本地环境变量提权思路原理:利用sh环境变量替换,使得/tmp/ps得到root权限;ps=sh过程:手写调用文件-编译-复制文件-增加环境变量-执行gccdemon1.c-oshellcp/bin/sh/tmp/psexportPATH=/tmp:$PATH#webshell权限无法设置环境变量./shellid提前本地定时任务(cronta......
  • .NET|--WPF|--笔记合集|--依赖项属性|--3.属性包装器
    前言属性包装器的主要作用是将依赖属性的访问方式转换为标准的CLR属性访问方式,从而使代码更加简洁、直观,并提供一致性和更好的开发体验。通过属性包装器,开发者可以利用依赖属性的高级功能,同时保持代码的可读性和易用性。"属性包装器"在TextBlock源码中使用publicclass......
  • [DPDK] Docker容器内安装DPDK
    Docker安装DPDK参考:容器安装DPDK。确认版本兼容性我使用的是Mellanox-5网卡。为了确认支持的DPDK版本,请先确认自己的OFED和frimware版本。查看firmware版本:$ibstatCA'mlx5_0'CAtype:MT4119Firmwareversion:16.35.3006查看OFED版本:$ofed_info-......
  • linux磁盘已满,查看哪个文件占用多
    使用df-h查看磁盘空间占用情况FilesystemSizeUsedAvailUse%Mountedonudev3.9G03.9G0%/devtmpfs799M3.1M796M1%/run/dev/vda199G99G0G100%/tmpfs3.9G03.9G0%/dev/shmtmpfs......
  • 一个免费好用的魔法
    这款虽然是免费的但一天只能免费一个小时,但你可以多造几个号就能一直免费用的时候要把火绒,360等类似的软件关了,不然有时候会得不了。因为是免费的所以有人数限制,一般在9.30之后人都特别多,只有到晚上或者中午和早上时候人少,手机端和PC端是分开的,手机端人是特别少的。官网连接:htt......
  • 网络安全公开数据集Maple-IDS,恶意流量检测数据集开放使用!
    MapleDataset枫叶数据集MapleDataset枫叶数据集由东北林业大学网络安全实验室(https://maple.nefu.edu.cn/lab/)公开发布,是用于入侵检测评估的数据集,其目的在于提升异常基础入侵检测系统(IDS)以及入侵预防系统(IPS)的性能与可靠性。在网络攻击愈发复杂的当下,拥有一个可靠且紧跟时代的......
  • vue3 导出为Excel文件
    服务端给的一个下载接口:/order/exportOrderOpenInvoice导出转化为ExcelconstexportOrder=async()=>{ letreqData={};  letexportOrderOpenInvoiceUrl="/order/exportOrderOpenInvoice";   try{   constresponse=awaitaxios.get(exportOrderOpenInvo......
  • 【网络知识系列】域名抢注
    原创祺印说信安以下文章来源于河南等级保护测评,作者铸盾安全一、概述域名仿冒尝试利用用户在地址栏中直接输入URL时引入的印刷错误(即“打字错误”)。通过利用用户错误,网络威胁行为者将毫无戒心的用户引导至与原始域名极为相似的非法域名。这种策略涉及购买和注册与现有域名......
  • vivo手机导出微信聊天记录方法
    1,先在手机上打开“开发人员选项”并将USB调试功能打开。再将手机通过数据线连接到电脑,打开电脑上已经安装好的“互传备份助手”(点击此处进入下载页面),再点击界面上的新建备份。注意:在电脑上运行互传备份助手时,会提醒手机上也要安装互传助手,按提示安装即可。 2,在互传备份助手窗......
  • 物质、质量、能量
    物质和质量宏观物质是由粒子构成,粒子没有质量这一概念,粒子有数量,粒子之间具有相互作用。所谓的质量是人为创造的一种概念术语,是粒子之间相互作用的一种宏观表现。基本粒子是否由单一物质构成,目前不清楚。我们平时所谓的对物体称重,实际上是在测量外物对被测物体的作用力。能......