Friday, January 3, 2014

How to add dependency property for custom control in wpf

Introduction

Ever had problem that your custom controls dependency property is not getting updated when you changed it from the control? Probably most of the wpf developer already know it still sharing it because, I kind of lost few minutes in darkness when I found that my custom control is not updating the target dependency property.

Enough talk show me the code

Well here is the code!. Do you find anything wrong with it? Seems absolutely fine.

public static readonly DependencyProperty SelectedValueProperty =
DependencyProperty.Register(
"SelectedValue", typeof(DateTime?), typeof(DateTimePicker), new UIPropertyMetadata(null, OnPropertyChanged));

public DateTime? SelectedValue
{
get
{
return (DateTime?)this.GetValue(SelectedValueProperty);
}
set
{
this.SetValue(SelectedValueProperty, value);
}
}

Now, my view model has a notify property which looks like the below code


public DateTime CurrentDate
{
get
{
return this.currentDate;
}
set
{
this.currentDate = value;
this.OnPropertyChanged("CurrentDate");
}
}

And the data is hooked via xaml binding, code below.


<riteq:DateTimePicker IsEnabled="True"
VerticalAlignment
="Top"
SelectedValue
="{Binding CurrentDate}"
x:Name
="TimePicker"
DisplayMode
="DateOnly"
CalendarSelectionMode
="SingleDate">
</riteq:DateTimePicker>

Look a perfect setup for the code. And at first glance we didn’t had any problem, until we tested it. No matter what date I select from my custom date picker, it never updating the CurrentData property of the view model.


So there is something wrong with the controls property. I tested and debug the code seems to be the binding expression working fine.


Then I found a piece of code where I set the dependency property’s value. As soon as i set some thing there the property’s binding got broken.


Here is the code.


if (this.cal.IsDateChanged)
{
this.SelectedValue = this.cal.SelectedDate;
}

Its a simple property setting , but this was causing problem, then when crazy with googling and found an every easy fix for my problem.


And the problem is with my definition of the dependency property. I was using “UIPropertyMetadata”. I changed the definition of property change call back to  “FrameworkPropertyMetadata”, and every thing back to normal and working again. here is the revised defination for the dependency property.


public static readonly DependencyProperty SelectedValueProperty =
DependencyProperty.Register(
"SelectedValue",
typeof(DateTime?),
typeof(DateTimePicker),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnPropertyChanged));

So now we are using FrameworkPropertyMetadata as property meta data. And that is the fix for my problem.


Lesson

If you need any dependency that can be changed inside the control please use FrameworkPropertyMetadata for dependency property definition.

No comments:

Post a Comment