属性值继承Property Value Inheritance

属性值继承是 Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) 属性系统的一项功能。Property value inheritance is a feature of the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) property system. 属性值继承使元素树中的子元素可以从父元素获取特定属性的值,并继承该值,就如同它是在最近的父元素中任意位置设置的一样。Property value inheritance enables child elements in a tree of elements to obtain the value of a particular property from parent elements, inheriting that value as it was set anywhere in the nearest parent element. 父元素可能也已通过属性值继承获得了其值,因此系统有可能一直递归到页面根。The parent element might also have obtained its value through property value inheritance, so the system potentially recurses all the way to the page root. 属性值继承不是默认属性系统行为;属性必须用特定的元数据设置来建立,以便使该属性对子元素启动属性值继承。Property value inheritance is not the default property system behavior; a property must be established with a particular metadata setting in order to cause that property to initiate property value inheritance on child elements.

属性值继承是内含继承Property Value Inheritance Is Containment Inheritance

此处作为术语的“继承”与类型和常规的面向对象的编程中提到的继承并非完全相同的概念,后者指派生类从其基类继承成员定义。"Inheritance" as a term here is not quite the same concept as inheritance in the context of types and general object-oriented programming, where derived classes inherit member definitions from their base classes. 继承的这一含义在 WPFWPF 中也适用:当在代码中用作元素且公开为成员时,各基类中定义的属性将公开为 XAMLXAML 派生类的特性。That meaning of inheritance is also active in WPFWPF: properties defined in various base classes are exposed as attributes for derived XAMLXAML classes when used as elements, and exposed as members for code. 属性值继承则是关于属性值如何基于元素树中的父子关系从一个元素继承到另一个元素。Property value inheritance is particularly about how property values can inherit from one element to another on the basis of the parent-child relationships within a tree of elements. 如果在 XAMLXAML 标记中定义应用程序时将元素嵌套在其他元素中,则该元素树在此种情况下最直接可见。That tree of elements is most directly visible when nesting elements inside other elements as you define applications in XAMLXAML markup. 还可以通过向其他对象的指定集合中添加对象来以编程方式创建对象树,在运行时,属性值继承在完成树中以相同方式工作。Trees of objects can also be created programmatically by adding objects to designated collections of other objects, and property value inheritance works the same way in the finished tree at run time.

属性值继承的实际应用Practical Applications of Property Value Inheritance

APIWPFWPF包括启用属性继承的几个属性。The WPFWPF APIs include several properties that have property inheritance enabled. 通常,使用这些属性的情况是当涉及到一个属性,每页可以仅对该属性设置一次,但是该属性还是某个基元素类的成员,因此还存在于大多数子元素中。Typically, the scenario for these is that they involve a property where it is appropriate that the property be set only once per page, but where that property is also a member of one of the base element classes and thus would also exist on most of the child elements. 例如,FlowDirection属性控制应在页面上显示和排列方向流的内容。For example, the FlowDirection property controls which direction flowed content should be presented and arranged on the page. 通常做法是在所有子元素中以一致的方式处理文本流概念。Typically, you want the text flow concept to be handled consistently throughout all child elements. 如果用户或环境操作因某种原因在元素树的某一层重置了流方向,则流方向通常会在整个树中重置。If flow direction were for some reason reset in some level of the element tree by user or environment action, it should typically be reset throughout. FlowDirection当属性被继承时,该值只需在元素树中包含应用程序中每个页面的表示需求的级别设置或重置一次。When the FlowDirection property is made to inherit, the value need only be set or reset once at the level in the element tree that encompasses the presentation needs of each page in the application. 即使是最初的默认值也将按照这种方式继承。Even the initial default value will inherit in this way. 在需有意混用流方向的极罕见情况下,属性值继承模型也仍允许个别元素重置该值。The property value inheritance model still enables individual elements to reset the value for the rare cases where having a mix of flow directions is intentional.

使自定义属性可继承Making a Custom Property Inheritable

通过更改自定义属性的元数据,还可以使自己的自定义属性可继承。By changing a custom property's metadata, you can also make your own custom properties inheritable. 但是,请注意,将属性指定为可继承需要考虑到性能问题。Note, however, that designating a property as inheritable does have some performance considerations. 如果该属性没有已建立的本地值或通过样式、模板或数据绑定获取的值,则可继承的属性会将赋予它的属性值提供给逻辑树中的所有子元素。In cases where that property does not have an established local value, or a value obtained through styles, templates, or data binding, an inheritable property provides its assigned property values to all child elements in the logical tree.

为了让属性参与值继承,请按照注册附加属性中所述创建自定义附加属性。To make a property participate in value inheritance, create a custom attached property, as described in Register an Attached Property. 使用元数据 (FrameworkPropertyMetadata) 注册属性,并在该元数据中的选项设置中指定"继承"选项。Register the property with metadata (FrameworkPropertyMetadata) and specify the "Inherits" option in the options settings within that metadata. 同时确保该属性已建立了默认值,因为该值现将继承。Also make sure that the property has an established default value, because that value will now inherit. 尽管已将该属性注册为附加属性,可能还需像对“非附加”依赖项属性一样,为所有者类型上的 get/set 访问创建属性“包装”。Although you registered the property as attached, you might also want to create a property "wrapper" for get/set access on the owner type, just as you would for an "nonattached" dependency property. 执行此操作后,可以使用所有者类型或派生类型的直接属性包装器设置可继承属性,也可以使用任何DependencyObject上的附加属性语法进行设置。After doing so, the inheritable property can either be set by using the direct property wrapper on the owner type or derived types, or it can be set by using the attached property syntax on any DependencyObject.

附加属性在概念上类似于全局属性;您可以检查任何DependencyObject值,并获得有效的结果。Attached properties are conceptually similar to global properties; you can check for the value on any DependencyObject and get a valid result. 附加属性的典型方案是在子元素上设置属性值,如果相关属性是附加属性,并且始终隐式地作为附加属性存在于树中的每个元素 (DependencyObject) 上,则该方案更为有效。The typical scenario for attached properties is to set property values on child elements, and that scenario is more effective if the property in question is an attached property that is always implicitly present as an attached property on each element (DependencyObject) in the tree.

备注

尽管属性值继承看起来对非附加依赖项属性有效,但通过运行时树中特定元素边界的非附加属性的继承行为并未定义。Although property value inheritance might appear to work for nonattached dependency properties, the inheritance behavior for a nonattached property through certain element boundaries in the run-time tree is undefined. 始终用于RegisterAttached注册在元数据中指定Inherits的属性。Always use RegisterAttached to register properties where you specify Inherits in the metadata.

跨树边界继承属性值Inheriting Property Values Across Tree Boundaries

属性继承通过遍历元素树来工作。Property inheritance works by traversing a tree of elements. 此树通常与逻辑树并行。This tree is often parallel to the logical tree. 但是,每当在定义元素树(如 a Brush) 的标记中包含 WPF 核心级对象时,您都创建了一个不连续的逻辑树。However, whenever you include a WPF core-level object in the markup that defines an element tree, such as a Brush, you have created a discontinuous logical tree. 真正的逻辑树在概念上不会通过 展开Brush,因为逻辑树是 WPF 框架级别的概念。A true logical tree does not conceptually extend through the Brush, because the logical tree is a WPF framework-level concept. 在使用 方法时,您可以看到这反映在结果中LogicalTreeHelperYou can see this reflected in the results when using the methods of LogicalTreeHelper. 但是,属性值继承可以桥接逻辑树中的此差距,并且仍然可以传递继承的值,只要可继承属性注册为附加属性,并且不会遇到故意的继承阻塞边界(如Framea )。However, property value inheritance can bridge this gap in the logical tree and can still pass inherited values through, so long as the inheritable property was registered as an attached property and no deliberate inheritance-blocking boundary (such as a Frame) is encountered.

另请参阅See also