How to Add Properties to Custom WPF Control
In the first post of this series I talked about some principles of creating a custom WPF control. In this post I want to jump in development details by talking about adding properties to a custom control.
Normal Properties
You know how to write properties for a class in .NET (is there anybody who doesn't know?!). But in WPF most elements use a special type of properties, Dependency Property. WPF uses dependency properties because they provide some extra features that are not provided in normal properties.
As I said in previous post there is a hierarchy for classes in WPF. As we derive our custom controls from FrameworkElement base class and this class is derived from DependencyObject (indirectly) then all our custom control classes have all requirements to support dependency properties.
To add a new property to a custom control class you can add a dependency property to it. This dependency property must be added to the static constructor of the class. You can store the value of this property into a static property.
On the other hand you can declare public get and set accessors for your property but it's also possible to call GetValue() and SetValue() methods from the base class.
Below is an example of adding a new property to a custom control. MyControl is a custom control that is derived from ItemsControl base class. ItemsCount is a new property for MyControl to work as a shortcut for its Items.Count property which is based on CountProperty dependency property and is already present in ItemsControl base class. In public static constructor I register this dependency property with DependencyProperty.Register() method. There is also a get and set accessor pair to access to this property.
public class MyControl : ItemsControl
{
static MyControl()
{
CountProperty = DependencyProperty.Register("Count",
typeof(int), typeof(MyControl));
}
static DependencyProperty CountProperty;
public int ItemsCount
{
get
{
return (int)base.GetValue(CountProperty);
}
set
{
base.SetValue(CountProperty, value);
}
}
}
Attached Properties
Another type of properties in WPF is attached property. Attached properties are some properties that belong to one element but are declared in other elements (i.e. Grid.Row or Grid.Column property for Grid element).
Defining an attached property is very similar to a normal property with a few differences. You must register an attached property with DependencyProperty.RegisterAttached() method and define your get and set accessors in a different way. In order to declare your accessors you need to write them manually and get a DependencyObject as target control and call its GetValue() and SetValue() methods.
Below is another example to declare MyAttachedProperty as an attached property.
public class MyControl : Control
{
static MyControl()
{
MyAttachedProperty = DependencyProperty.RegisterAttached("MyAttached",
typeof(int), typeof(MyControl));
}
static DependencyProperty MyAttachedProperty;
public static int GetCountProperty(DependencyObject target)
{
return (int)target.GetValue(MyAttachedProperty);
}
public static void SetCountProperty(DependencyObject target, int value)
{
target.SetValue(MyAttachedProperty, value);
}
}
Property Invalidation
The last thing that should be mentioned about properties in a custom control is property invalidation. Sometimes you need to be aware of property changes to update your code based on these changes. Adding property invalidation callbacks to a custom control is as easy as adding a PropertyChangedCallback object to a PropertyMetadata object and add this PropertyMetadata object to Register() or RegisterAttached() methods. In the last example I updated the code of first example to call a method when CountProperty value is changed.
public class MyControl : ItemsControl
{
static MyControl()
{
PropertyChangedCallback countChangedCallback =
new PropertyChangedCallback(CountChanged);
PropertyMetadata metaData =
new PropertyMetadata(countChangedCallback);
CountProperty = DependencyProperty.Register("Count",
typeof(int), typeof(MyControl), metaData);
}
static DependencyProperty CountProperty;
public int ItemsCount
{
get
{
return (int)base.GetValue(CountProperty);
}
set
{
base.SetValue(CountProperty, value);
}
}
static void CountChanged(DependencyObject property,
DependencyPropertyChangedEventArgs args)
{
MessageBox.Show("Count is changed!");
}
}
If you're looking for a sample to show the result in a custom control, wait until I finish my posts then I'll create a simple control and will apply it in an application to show how these things work together.
[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.
8 Comments : 04.28.07
Feedbacks
Hey just tried ur method on a Textbox and its working perfectly as far as adding properties and events is concerned. But when I add similar syntax properties to my comb0o box while loading the assembly into the Toolbox, it gives an error stating that there are no user controls for this assembly !!! CAn u plz guide me with this dilemma !!! Thanks a ton !!! :-)
Hi, I am creating custom control with a textbox.
How can I access the Text property of textbox control from class.
pls help.
Nice sample, I too am working on WPF lately.
BTW, bought your book last month and I must say it covers the huge topic of VS integration quite throughly.
Thanks,
Kavan

#1
DotNetKicks.com
04.28.2007 @ 11:59 AM