框架属性元数据 (WPF .NET)

可以在 Windows Presentation Foundation (WPF) 框架级别为依赖属性设置框架属性元数据选项。 当 WPF 演示 API 和可执行文件处理呈现和数据绑定时,WPF 框架级别规定适用。 演示 API 和可执行文件查询依赖属性的 FrameworkPropertyMetadata

重要

面向 .NET 7 和 .NET 6 的桌面指南文档正在撰写中。

先决条件

本文假定你对依赖属性有基本的了解,并且已阅读依赖属性概述。 若要理解本文中的示例,还应当熟悉 Extensible Application Markup Language (XAML) 并知道如何编写 WPF 应用程序。

框架属性元数据类别

FrameworkPropertyMetadata 分为以下类别:

  • 影响元素布局(特别是 AffectsArrangeAffectsMeasureAffectsRender 元数据标志)的元数据。 如果你的依赖属性实现影响视觉对象方面,并且要在类中实现 MeasureOverrideArrangeOverride,则可设置这些标志。 MeasureOverrideArrangeOverride 方法向布局系统提供特定于实现的行为和呈现信息。 当在依赖属性的元数据中将 AffectsArrangeAffectsMeasureAffectsRender 设置为 true 并且该依赖属性的有效值发生更改时,WPF 属性系统将发起一个请求,使元素的视觉对象失效以触发重绘。

  • 影响某个元素的父元素的布局(特别是 AffectsParentArrangeAffectsParentMeasure 元数据标志)的元数据。 设置这些标志的 WPF 依赖属性的示例有 FixedPage.LeftParagraph.KeepWithNext

  • 属性值继承元数据,特别是 InheritsOverridesInheritanceBehavior 元数据标志。 默认情况下,依赖属性不会继承值。 OverridesInheritanceBehavior 允许将继承的路径也纳入可视化树,这对于某些控件复合方案来说是必需的。 有关详细信息,请参阅属性值继承

    注意

    属性值上下文中的术语“继承”特定于依赖属性,与托管代码类型和通过派生类型的成员继承没有直接关系。 在依赖属性的上下文中,这意味着子元素可以从父元素继承依赖属性值。

  • 数据绑定元数据,特别是 BindsTwoWayByDefaultIsNotDataBindable 元数据标志。 默认情况下,WPF 框架中的依赖属性支持单向绑定。 考虑将双向绑定设置为报告状态且可通过用户操作来修改的属性的默认设置,例如 IsSelected。 此外,当控件的用户希望某个属性来实现双向绑定时,请考虑将双向绑定设置为默认设置,例如 TextBox.TextBindsTwoWayByDefault 仅影响默认绑定模式。 若要编辑绑定的数据流方向,请设置 Binding.Mode。 当数据绑定没有用例时,可使用 IsNotDataBindable 禁用数据绑定。 有关数据绑定的详细信息,请参阅数据绑定概述

  • 日志元数据,特别是 Journal 元数据标志。 仅对于某些依赖属性(如 SelectedIndex),Journal 标志的默认值才为 true。 用户输入控件应为其值包含需要存储的用户选择的属性设置 Journal 标志。 Journal 标志由支持日志的应用程序或服务读取,包括 WPF 日志服务。 有关存储导航步骤的信息,请参阅导航概述

FrameworkPropertyMetadata 直接派生自 UIPropertyMetadata,并实现此处讨论的标志。 除非专门设置,否则 FrameworkPropertyMetadata 标志的默认值为 false

读取 FrameworkPropertyMetadata

若要检索依赖属性的元数据,请对 DependencyProperty 标识符调用 GetMetadataGetMetadata 调用返回 PropertyMetadata 对象。 如果需要查询框架元数据值,请将 PropertyMetadata 强制转换为 FrameworkPropertyMetadata

指定 FrameworkPropertyMetadata

注册依赖属性时,可以选择创建元数据并将元数据分配给它。 所分配的元数据对象可以是 PropertyMetadata 或其派生类之一,例如 FrameworkPropertyMetadata。 对于依赖于 WPF 演示文稿 API 和可执行文件进行呈现和数据绑定的依赖属性,请选择 FrameworkPropertyMetadata。 更高级的选项是从 FrameworkPropertyMetadata 派生以创建具有更多标志的自定义元数据报告类。 或者,可将 UIPropertyMetadata 用于影响 UI 呈现的非框架属性。

尽管元数据选项通常是在注册新依赖属性期间设置的,但你可以在 OverrideMetadataAddOwner 调用中重新指定。 替代元数据时,始终使用属性注册期间使用的相同元数据类型替代。

FrameworkPropertyMetadata 公开的属性特征有时称为标志。 如果要创建 FrameworkPropertyMetadata 实例,可通过两种方式填充标志值:

  1. FrameworkPropertyMetadataOptions 枚举类型的实例上设置标志。 FrameworkPropertyMetadataOptions 允许按位“或”组合指定元数据标志。 然后,使用具有 FrameworkPropertyMetadata 参数的构造函数实例化 FrameworkPropertyMetadataOptions,并传入 FrameworkPropertyMetadataOptions 实例。 若要在将 FrameworkPropertyMetadataOptions 传入 FrameworkPropertyMetadata 构造函数后更改元数据标志,请更改新 FrameworkPropertyMetadata 实例上的相应属性。 例如,如果设置了 FrameworkPropertyMetadataOptions.NotDataBindable 标志,则可通过将 FrameworkPropertyMetadata.IsNotDataBindable 设置为 false 来撤消该标志。

  2. 使用不具有 FrameworkPropertyMetadata 参数的构造函数实例化 FrameworkPropertyMetadataOptions,然后对 FrameworkPropertyMetadata 设置适用的 Boolean 标志。 在将 FrameworkPropertyMetadata 实例与依赖属性关联之前设置标志值,否则将出现 InvalidOperationException

元数据替代行为

替代框架属性元数据时,更改的元数据值将替换原始值或与原始值合并:

  • 对于 PropertyChangedCallback,默认合并逻辑将在一个表中保留以前的 PropertyChangedCallback 值,并在属性更改时调用所有值。 回调顺序取决于类深度,其中由层次结构中的基类注册的回调将首先运行。 继承的回调仅运行一次,并且由将它们添加到元数据中的类拥有。

  • 对于 DefaultValue,新值将替换现有的默认值。 如果未在替代元数据中指定 DefaultValue,并且现有的 FrameworkPropertyMetadata 已设置 Inherits 标志,则该默认值来自在元数据中指定 DefaultValue 的最近上级。

  • 对于 CoerceValueCallback,新值将替换现有的 CoerceValueCallback 值。 如果未在替代元数据中指定 CoerceValueCallback,则该值来自指定 CoerceValueCallback 的继承链中最近的上级。

  • 对于 FrameworkPropertyMetadata 非继承标志,可使用 true 值替代默认 false 值。 但对于 InheritsJournalOverridesInheritanceBehaviorSubPropertiesDoNotAffectRender,只能使用 false 值替代 true 值。

注意

默认合并逻辑由 Merge 方法实现。 你可以在继承依赖属性的派生类中指定自定义合并逻辑,方法是替代该类中的 Merge

另请参阅