public static readonly DependencyProperty MyCustomProperty = DependencyProperty.Register("MyCustom", typeof(string), typeof(Window1));
public string MyCustom
{
get
{
return this.GetValue(MyCustomProperty) as string;
}
set
{
this.SetValue(MyCustomProperty, value);
}
}
Defining a dependency property
public static readonly DependencyProperty FontSizeProperty;
Creating or Registering a Dependency Property
FontSizeProperty = DependencyProperty.Register("FontSize", typeof(double),
typeof(Control));
The arguments are the text name of the property associated with the dependency property, the data type of the property, and the class type registering the property. In actuality, there's usually some more code involved. The DependencyProperty object often includes metadata that describes some crucial aspects of the property.
GetValue and SetValue
Where do the SetValue and GetValue methods come from? These methods are defined in the DependencyObject class from which much of the WPF descends:
Object
----DispatcherObject (abstract)
--------DependencyObject
------------Visual (abstract)
--------------------UIElement
-----------------------------FrameworkElement
------------------------------------Control
Watch out for similar names: Both DependencyObject and DependencyProperty are classes. Many classes in the WPF descend from DependencyObject and thus have SetValue and GetValue methods. These methods work with fields defined as static DependencyProperty objects.
Even though the DependencyProperty object passed to the SetValue and GetValue methods is static, SetValue and GetValue are instance methods, and they are setting and obtaining values associated with the particular instance. The DependencyObject is maintaining the current value, and handling all the routine stuff as well. For example, if SetValue hasn't yet been called for the particular Control instance, GetValue returns the value of the DefaultValue property associated with the metadata of FontSizeProperty.
When a program such as SetFontSizeProperty sets the FontSize property, the SetValue method has some work to do. The method must call the validation method to determine if the value is proper. If not, it throws an exception. Because the AffectsMeasure flag is set for FontSizeProperty, the SetValue method must cause a recalculation in the size of the control, which also requires the control to be redrawn. That redrawing logic uses the new FontSize in displaying text. (For a property like Foreground, the AffectsMeasure flag is false but the AffectsRender flag is true. The control isn't resized, but it is redrawn.) The SetValue method must also pass the new value down through the tree as a result of the Inherits flag. Elements in the tree can accept that new value for themselves, or reject it if their own FontSize property has been explicitly set.
Although examining how the FontSize property works is certainly helpful in understanding dependency properties, the lessons are hammered home only when you define a dependency property on your own.
The class that follows inherits from Button but includes a new dependency property. This class is called SpaceButton, and before you get ideas about launching buttons into orbit, you should know that the SpaceButton merely displays text with spaces inserted between each letter. SpaceButton adds two properties to those found in the normal Button class: Text and Space. For contrast, the class implements the Text property as a traditional .NET property, while the Space property is implemented in conjunction with a dependency property. The SpaceButton sets its Content property to the Text string with spaces inserted as indicated by the value of the Space property.
Naming Convention
It should also be noted that you should not write your logic inside the Wrapper property as it will not be called every time the property is called for. It will internally call the GetValue and SetValue itself. So if you want to write your own logic when the dependency property is fetched, there are callbacks to do them.
No comments:
Post a Comment