mirror of
https://github.com/Stone-Red-Code/docs-desktop.git
synced 2026-09-07 07:56:07 +02:00
Replace various WPF include files with content (#1335)
* net-current-v30plus-md.md * net-current-v40plus-md.md * tla2sharptla-ui-md.md * tla2sharptla-uiautomation-md.md * tla2sharptla-winclient-md.md * tla2sharptla-xaml-md.md * tlasharptla-ui-md.md * tlasharptla-uiautomation-md.md * tlasharptla-winclient-md.md * tlasharptla-xaml-md.md * fix warnings
This commit is contained in:
@@ -19,33 +19,33 @@ ms.assetid: e6bfcfac-b10d-4f58-9f77-a864c2a2938f
|
||||
---
|
||||
# Custom Dependency Properties
|
||||
|
||||
This topic describes the reasons that [!INCLUDE[TLA#tla_winclient](../../../includes/tlasharptla-winclient-md.md)] application developers and component authors might want to create custom dependency property, and describes the implementation steps as well as some implementation options that can improve performance, usability, or versatility of the property.
|
||||
This topic describes the reasons that Windows Presentation Foundation (WPF) application developers and component authors might want to create custom dependency property, and describes the implementation steps as well as some implementation options that can improve performance, usability, or versatility of the property.
|
||||
|
||||
<a name="prerequisites"></a>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This topic assumes that you understand dependency properties from the perspective of a consumer of existing dependency properties on [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] classes, and have read the [Dependency Properties Overview](dependency-properties-overview.md) topic. In order to follow the examples in this topic, you should also understand [!INCLUDE[TLA#tla_xaml](../../../includes/tlasharptla-xaml-md.md)] and know how to write [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] applications.
|
||||
This topic assumes that you understand dependency properties from the perspective of a consumer of existing dependency properties on WPF classes, and have read the [Dependency Properties Overview](dependency-properties-overview.md) topic. In order to follow the examples in this topic, you should also understand WPF applications.
|
||||
|
||||
<a name="whatis"></a>
|
||||
|
||||
## What Is a Dependency Property?
|
||||
|
||||
You can enable what would otherwise be a common language runtime (CLR) property to support styling, data binding, inheritance, animations, and default values by implementing it as a dependency property. Dependency properties are properties that are registered with the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] property system by calling the <xref:System.Windows.DependencyProperty.Register%2A> method (or <xref:System.Windows.DependencyProperty.RegisterReadOnly%2A>), and that are backed by a <xref:System.Windows.DependencyProperty> identifier field. Dependency properties can be used only by <xref:System.Windows.DependencyObject> types, but <xref:System.Windows.DependencyObject> is quite high in the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] class hierarchy, so the majority of classes available in [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] can support dependency properties. For more information about dependency properties and some of the terminology and conventions used for describing them in this SDK, see [Dependency Properties Overview](dependency-properties-overview.md).
|
||||
You can enable what would otherwise be a common language runtime (CLR) property to support styling, data binding, inheritance, animations, and default values by implementing it as a dependency property. Dependency properties are properties that are registered with the WPF property system by calling the <xref:System.Windows.DependencyProperty.Register%2A> method (or <xref:System.Windows.DependencyProperty.RegisterReadOnly%2A>), and that are backed by a <xref:System.Windows.DependencyProperty> identifier field. Dependency properties can be used only by <xref:System.Windows.DependencyObject> types, but <xref:System.Windows.DependencyObject> is quite high in the WPF class hierarchy, so the majority of classes available in WPF can support dependency properties. For more information about dependency properties and some of the terminology and conventions used for describing them in this SDK, see [Dependency Properties Overview](dependency-properties-overview.md).
|
||||
|
||||
<a name="example_dp"></a>
|
||||
|
||||
## Examples of Dependency Properties
|
||||
|
||||
Examples of dependency properties that are implemented on [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] classes include the <xref:System.Windows.Controls.Control.Background%2A> property, the <xref:System.Windows.FrameworkElement.Width%2A> property, and the <xref:System.Windows.Controls.TextBox.Text%2A> property, among many others. Each dependency property exposed by a class has a corresponding public static field of type <xref:System.Windows.DependencyProperty> exposed on that same class. This is the identifier for the dependency property. The identifier is named using a convention: the name of the dependency property with the string `Property` appended to it. For example, the corresponding <xref:System.Windows.DependencyProperty> identifier field for the <xref:System.Windows.Controls.Control.Background%2A> property is <xref:System.Windows.Controls.Control.BackgroundProperty>. The identifier stores the information about the dependency property as it was registered, and the identifier is then used later for other operations involving the dependency property, such as calling <xref:System.Windows.DependencyObject.SetValue%2A>.
|
||||
Examples of dependency properties that are implemented on WPF classes include the <xref:System.Windows.Controls.Control.Background%2A> property, the <xref:System.Windows.FrameworkElement.Width%2A> property, and the <xref:System.Windows.Controls.TextBox.Text%2A> property, among many others. Each dependency property exposed by a class has a corresponding public static field of type <xref:System.Windows.DependencyProperty> exposed on that same class. This is the identifier for the dependency property. The identifier is named using a convention: the name of the dependency property with the string `Property` appended to it. For example, the corresponding <xref:System.Windows.DependencyProperty> identifier field for the <xref:System.Windows.Controls.Control.Background%2A> property is <xref:System.Windows.Controls.Control.BackgroundProperty>. The identifier stores the information about the dependency property as it was registered, and the identifier is then used later for other operations involving the dependency property, such as calling <xref:System.Windows.DependencyObject.SetValue%2A>.
|
||||
|
||||
As mentioned in the [Dependency Properties Overview](dependency-properties-overview.md), all dependency properties in [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] (except most attached properties) are also CLR properties because of the "wrapper" implementation. Therefore, from code, you can get or set dependency properties by calling CLR accessors that define the wrappers in the same manner that you would use other CLR properties. As a consumer of established dependency properties, you do not typically use the <xref:System.Windows.DependencyObject> methods <xref:System.Windows.DependencyObject.GetValue%2A> and <xref:System.Windows.DependencyObject.SetValue%2A>, which are the connection point to the underlying property system. Rather, the existing implementation of the CLR properties will have already called <xref:System.Windows.DependencyObject.GetValue%2A> and <xref:System.Windows.DependencyObject.SetValue%2A> within the `get` and `set` wrapper implementations of the property, using the identifier field appropriately. If you are implementing a custom dependency property yourself, then you will be defining the wrapper in a similar way.
|
||||
As mentioned in the [Dependency Properties Overview](dependency-properties-overview.md), all dependency properties in WPF (except most attached properties) are also CLR properties because of the "wrapper" implementation. Therefore, from code, you can get or set dependency properties by calling CLR accessors that define the wrappers in the same manner that you would use other CLR properties. As a consumer of established dependency properties, you do not typically use the <xref:System.Windows.DependencyObject> methods <xref:System.Windows.DependencyObject.GetValue%2A> and <xref:System.Windows.DependencyObject.SetValue%2A>, which are the connection point to the underlying property system. Rather, the existing implementation of the CLR properties will have already called <xref:System.Windows.DependencyObject.GetValue%2A> and <xref:System.Windows.DependencyObject.SetValue%2A> within the `get` and `set` wrapper implementations of the property, using the identifier field appropriately. If you are implementing a custom dependency property yourself, then you will be defining the wrapper in a similar way.
|
||||
|
||||
<a name="backing_with_dp"></a>
|
||||
|
||||
## When Should You Implement a Dependency Property?
|
||||
|
||||
When you implement a property on a class, so long as your class derives from <xref:System.Windows.DependencyObject>, you have the option to back your property with a <xref:System.Windows.DependencyProperty> identifier and thus to make it a dependency property. Having your property be a dependency property is not always necessary or appropriate, and will depend on your scenario needs. Sometimes, the typical technique of backing your property with a private field is adequate. However, you should implement your property as a dependency property whenever you want your property to support one or more of the following [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] capabilities:
|
||||
When you implement a property on a class, so long as your class derives from <xref:System.Windows.DependencyObject>, you have the option to back your property with a <xref:System.Windows.DependencyProperty> identifier and thus to make it a dependency property. Having your property be a dependency property is not always necessary or appropriate, and will depend on your scenario needs. Sometimes, the typical technique of backing your property with a private field is adequate. However, you should implement your property as a dependency property whenever you want your property to support one or more of the following WPF capabilities:
|
||||
|
||||
- You want your property to be settable in a style. For more information, see [Styling and Templating](../controls/styles-templates-overview.md).
|
||||
|
||||
@@ -59,11 +59,11 @@ When you implement a property on a class, so long as your class derives from <xr
|
||||
|
||||
- You want the property system to report when the previous value of the property has been changed by actions taken by the property system, the environment, or the user, or by reading and using styles. By using property metadata, your property can specify a callback method that will be invoked each time the property system determines that your property value was definitively changed. A related concept is property value coercion. For more information, see [Dependency Property Callbacks and Validation](dependency-property-callbacks-and-validation.md).
|
||||
|
||||
- You want to use established metadata conventions that are also used by [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] processes, such as reporting whether changing a property value should require the layout system to recompose the visuals for an element. Or you want to be able to use metadata overrides so that derived classes can change metadata-based characteristics such as the default value.
|
||||
- You want to use established metadata conventions that are also used by WPF processes, such as reporting whether changing a property value should require the layout system to recompose the visuals for an element. Or you want to be able to use metadata overrides so that derived classes can change metadata-based characteristics such as the default value.
|
||||
|
||||
- You want properties of a custom control to receive Visual Studio WPF Designer support, such as **Properties** window editing. For more information, see [Control Authoring Overview](../controls/control-authoring-overview.md).
|
||||
|
||||
When you examine these scenarios, you should also consider whether you can achieve your scenario by overriding the metadata of an existing dependency property, rather than implementing a completely new property. Whether a metadata override is practical depends on your scenario and how closely that scenario resembles the implementation in existing [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] dependency properties and classes. For more information about overriding metadata on existing properties, see [Dependency Property Metadata](dependency-property-metadata.md).
|
||||
When you examine these scenarios, you should also consider whether you can achieve your scenario by overriding the metadata of an existing dependency property, rather than implementing a completely new property. Whether a metadata override is practical depends on your scenario and how closely that scenario resembles the implementation in existing WPF dependency properties and classes. For more information about overriding metadata on existing properties, see [Dependency Property Metadata](dependency-property-metadata.md).
|
||||
|
||||
<a name="checklist"></a>
|
||||
|
||||
@@ -96,7 +96,7 @@ There are established naming conventions regarding dependency properties that yo
|
||||
|
||||
The dependency property itself will have a basic name, "AquariumGraphic" as in this example, which is given as the first parameter of <xref:System.Windows.DependencyProperty.Register%2A>. That name must be unique within each registering type. Dependency properties inherited through base types are considered to be already part of the registering type; names of inherited properties cannot be registered again. However, there is a technique for adding a class as owner of a dependency property even when that dependency property is not inherited; for details, see [Dependency Property Metadata](dependency-property-metadata.md).
|
||||
|
||||
When you create the identifier field, name this field by the name of the property as you registered it, plus the suffix `Property`. This field is your identifier for the dependency property, and it will be used later as an input for the <xref:System.Windows.DependencyObject.SetValue%2A> and <xref:System.Windows.DependencyObject.GetValue%2A> calls you will make in the wrappers, by any other code access to the property by your own code, by any external code access you allow, by the property system, and potentially by [!INCLUDE[TLA2#tla_xaml](../../../includes/tla2sharptla-xaml-md.md)] processors.
|
||||
When you create the identifier field, name this field by the name of the property as you registered it, plus the suffix `Property`. This field is your identifier for the dependency property, and it will be used later as an input for the <xref:System.Windows.DependencyObject.SetValue%2A> and <xref:System.Windows.DependencyObject.GetValue%2A> calls you will make in the wrappers, by any other code access to the property by your own code, by any external code access you allow, by the property system, and potentially by XAML processors.
|
||||
|
||||
> [!NOTE]
|
||||
> Defining the dependency property in the class body is the typical implementation, but it is also possible to define a dependency property in the class static constructor. This approach might make sense if you need more than one line of code to initialize the dependency property.
|
||||
@@ -109,7 +109,7 @@ Your wrapper implementation should call <xref:System.Windows.DependencyObject.Ge
|
||||
|
||||
In all but exceptional circumstances, your wrapper implementations should perform only the <xref:System.Windows.DependencyObject.GetValue%2A> and <xref:System.Windows.DependencyObject.SetValue%2A> actions, respectively. The reason for this is discussed in the topic [XAML Loading and Dependency Properties](xaml-loading-and-dependency-properties.md).
|
||||
|
||||
All existing public dependency properties that are provided on the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] classes use this simple wrapper implementation model; most of the complexity of how dependency properties work is either inherently a behavior of the property system, or is implemented through other concepts such as coercion or property change callbacks through property metadata.
|
||||
All existing public dependency properties that are provided on the WPF classes use this simple wrapper implementation model; most of the complexity of how dependency properties work is either inherently a behavior of the property system, or is implemented through other concepts such as coercion or property change callbacks through property metadata.
|
||||
|
||||
[!code-csharp[WPFAquariumSln#AGWithWrapper](~/samples/snippets/csharp/VS_Snippets_Wpf/WPFAquariumSln/CSharp/WPFAquariumObjects/Class1.cs#agwithwrapper)]
|
||||
[!code-vb[WPFAquariumSln#AGWithWrapper](~/samples/snippets/visualbasic/VS_Snippets_Wpf/WPFAquariumSln/visualbasic/wpfaquariumobjects/class1.vb#agwithwrapper)]
|
||||
@@ -118,9 +118,9 @@ Again, by convention, the name of the wrapper property must be the same as the n
|
||||
|
||||
- Certain aspects of styles and templates will not work.
|
||||
|
||||
- Most tools and designers must rely on the naming conventions to properly serialize [!INCLUDE[TLA2#tla_xaml](../../../includes/tla2sharptla-xaml-md.md)], or to provide designer environment assistance at a per-property level.
|
||||
- Most tools and designers must rely on the naming conventions to properly serialize XAML, or to provide designer environment assistance at a per-property level.
|
||||
|
||||
- The current implementation of the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] [!INCLUDE[TLA2#tla_xaml](../../../includes/tla2sharptla-xaml-md.md)] loader bypasses the wrappers entirely, and relies on the naming convention when processing attribute values. For more information, see [XAML Loading and Dependency Properties](xaml-loading-and-dependency-properties.md).
|
||||
- The current implementation of the WPF XAML loader bypasses the wrappers entirely, and relies on the naming convention when processing attribute values. For more information, see [XAML Loading and Dependency Properties](xaml-loading-and-dependency-properties.md).
|
||||
|
||||
<a name="metadata"></a>
|
||||
|
||||
@@ -134,11 +134,11 @@ For <xref:System.Windows.FrameworkPropertyMetadata>, you can also specify metada
|
||||
|
||||
#### Setting Appropriate Metadata Flags
|
||||
|
||||
- If your property (or changes in its value) affects the [!INCLUDE[TLA#tla_ui](../../../includes/tlasharptla-ui-md.md)], and in particular affects how the layout system should size or render your element in a page, set one or more of the following flags: <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsMeasure>, <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsArrange>, <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsRender>.
|
||||
- If your property (or changes in its value) affects the user interface (UI), and in particular affects how the layout system should size or render your element in a page, set one or more of the following flags: <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsMeasure>, <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsArrange>, <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsRender>.
|
||||
|
||||
- <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsMeasure> indicates that a change to this property requires a change to [!INCLUDE[TLA2#tla_ui](../../../includes/tla2sharptla-ui-md.md)] rendering where the containing object might require more or less space within the parent. For example, a "Width" property should have this flag set.
|
||||
- <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsMeasure> indicates that a change to this property requires a change to UI rendering where the containing object might require more or less space within the parent. For example, a "Width" property should have this flag set.
|
||||
|
||||
- <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsArrange> indicates that a change to this property requires a change to [!INCLUDE[TLA2#tla_ui](../../../includes/tla2sharptla-ui-md.md)] rendering that typically does not require a change in the dedicated space, but does indicate that the positioning within the space has changed. For example, an "Alignment" property should have this flag set.
|
||||
- <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsArrange> indicates that a change to this property requires a change to UI rendering that typically does not require a change in the dedicated space, but does indicate that the positioning within the space has changed. For example, an "Alignment" property should have this flag set.
|
||||
|
||||
- <xref:System.Windows.FrameworkPropertyMetadataOptions.AffectsRender> indicates that some other change has occurred that will not affect layout and measure, but does require another render. An example would be a property that changes a color of an existing element, such as "Background".
|
||||
|
||||
@@ -176,7 +176,7 @@ Dependency properties should be declared as public properties. Dependency proper
|
||||
|
||||
## Dependency Properties and Class Constructors
|
||||
|
||||
There is a general principle in managed code programming (often enforced by code analysis tools such as FxCop) that class constructors should not call virtual methods. This is because constructors can be called as base initialization of a derived class constructor, and entering the virtual method through the constructor might occur at an incomplete initialization state of the object instance being constructed. When you derive from any class that already derives from <xref:System.Windows.DependencyObject>, you should be aware that the property system itself calls and exposes virtual methods internally. These virtual methods are part of the [!INCLUDE[TLA2#tla_winclient](../../../includes/tla2sharptla-winclient-md.md)] property system services. Overriding the methods enables derived classes to participate in value determination. To avoid potential issues with runtime initialization, you should not set dependency property values within constructors of classes, unless you follow a very specific constructor pattern. For details, see [Safe Constructor Patterns for DependencyObjects](safe-constructor-patterns-for-dependencyobjects.md).
|
||||
There is a general principle in managed code programming (often enforced by code analysis tools such as FxCop) that class constructors should not call virtual methods. This is because constructors can be called as base initialization of a derived class constructor, and entering the virtual method through the constructor might occur at an incomplete initialization state of the object instance being constructed. When you derive from any class that already derives from <xref:System.Windows.DependencyObject>, you should be aware that the property system itself calls and exposes virtual methods internally. These virtual methods are part of the WPF property system services. Overriding the methods enables derived classes to participate in value determination. To avoid potential issues with runtime initialization, you should not set dependency property values within constructors of classes, unless you follow a very specific constructor pattern. For details, see [Safe Constructor Patterns for DependencyObjects](safe-constructor-patterns-for-dependencyobjects.md).
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
Reference in New Issue
Block a user