DependencyProperty.AddOwner Method (Type, PropertyMetadata)
http://msdn.microsoft.com/zh-cn/library/ms597484.aspx
#region text public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } //public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", // typeof(string), typeof(IconButton), new PropertyMetadata(string.Empty)); public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(typeof(IconButton)); #endregion
This method enables the property system to recognize a dependency property on a type that did not register that particular dependency property initially. The return value of this method is used to declare and expose the dependency property, particularly as it exists on the adding owner class.Generally, the same property name for both original owner and added owner should be used to indicate the similar functionality.It is good practice to expose the identifiers, as well as new CLR property wrappers, for dependency properties that are added to types using AddOwner. The AddOwner methodology recommended above is used when creating APIs declared within WPF.For instance, both Border and Control define a BorderBrush dependency property, which have similar functionality.Control defines its BorderBrush property to the property system by calling AddOwner on original owner Border and its registered BorderBrushProperty dependency property identifer.The AddOwner return value is then used to establish a static DependencyProperty field (BorderBrushProperty)for that property on the added owner, and a BorderBrush property wrapper is also declared. The added owner's dependency property identifier should be used for operations such as GetValue.However, type-specific operations involving either types or instances of the class that was added as owner with different metadata will still return the expected results even if the original (not the added owner's) dependency property identifier is specified in calls to methods such as GetValue or GetMetadata.The metadata for the added owner is perpetuated by the AddOwner call itself, not necessarily referenced exclusively by the adding owner class identifier field.Nevertheless, it is good practice to expose the identifier, as well as new CLR property wrappers, for dependency properties that are added to types using AddOwner, because failing to do so creates disparity between the CLR and XAML representations of your properties. The supplied metadata is merged with the property metadata for the dependency property as it exists on the base owner.Any characteristics that were specified in the original base metadata will persist.Only those characteristics that were specifically changed in the new metadata will override the characteristics of the base metadata.Some characteristics, such as DefaultValue, are replaced if they are specified in the new metadata.Others, such as PropertyChangedCallback, are combined.Ultimately, the merge behavior depends on the property metadata type being used for the override, so the behavior described here is for the existing property metadata classes used by WPF dependency properties.For details, see Dependency Property Metadata and Framework Property Metadata.
Examples
--------------------------------------------------------------------------------
This example shows how to add a class as an owner of a dependency property registered for a different type. By doing this, the WPF XAML reader and property system are both able to recognize the class as an additional owner of the property. Adding as owner optionally allows the adding class to provide type-specific metadata. In the following example, StateProperty is a property registered by the MyStateControl class. The class UnrelatedStateControl adds itself as an owner of the StateProperty using the AddOwner method, specifically using the signature that allows for new metadata for the dependency property as it exists on the adding type. Notice that you should provide common language runtime (CLR) accessors for the property similar to the example shown in the How to: Implement a Dependency Property example, as well as re-expose the dependency property identifier on the class being added as owner. Without wrappers, the dependency property would still work from the perspective of programmatic access using GetValue or SetValue. But you typically want to parallel this property-system behavior with the CLR property wrappers. The wrappers make it easier to set the dependency property programmatically, and make it possible to set the properties as XAML attributes. To find out how to override default metadata, see How to: Override Metadata for a Dependency Property.
public class MyStateControl : ButtonBase { public MyStateControl() : base() { } public Boolean State { get { return (Boolean)this.GetValue(StateProperty); } set { this.SetValue(StateProperty, value); } } public static readonly DependencyProperty StateProperty = DependencyProperty.Register( "State", typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(false)); } ... public class UnrelatedStateControl : Control { public UnrelatedStateControl() { } public static readonly DependencyProperty StateProperty = MyStateControl.StateProperty.AddOwner(typeof(UnrelatedStateControl), new PropertyMetadata(true)); public Boolean State { get { return (Boolean)this.GetValue(StateProperty); } set { this.SetValue(StateProperty, value); } } }