Tuesday, January 25, 2011

wpftoolkit datepicker infinite loop and lost focus issue

When the value in the datepicker has changed, the datepicker will Invalidate the control to get the current value. This will cause .net to reevaluate the control which in turn fires the bindings and converters etc., as well as the LostFocus event.

When evaluating the current value the DatePicker will try to parse the current value as a DateTime?. Because a DateTime object is aware of time as well as the current Date, it will realise that the property that you have bound to has changed, because the current time of the control has also changed. This will fire all the bindings again to notify that the property has changed.
The event will also force the focus property again and will try to Invalidate the control to get the current value again, based on your binding.

The result is an infinite loop or a stackoverflow exception.

This rarely happens, but is the result of the binding. This especially happens when the binding property NotifyOnSourceUpdated = true and UpdateSourceTrigger= OnPropertyChanged.

In my case I had to create a multi-binding and the properties were just firing all over the place.

The datepicker wants a DateTime? (nullable date time), because it accepts a text value, and a text value can be an invalid date. Normally we bind to a DateTime object because we want a definite value. The binding mentioned above will then cause constant conversion and the propertychanged event to fire repeatedly.

Luckily the solution was easy for me: Bind to a DateTime? and cast the value to a DateTime.

Because a DateTime? can take in a null value if the conversion failed, you don’t have to worry about an invalid value Invalidating the control again.

e.g.

private DateTime? dtValueDate;

public DateTime? ValueDate
{
get
{
if (dtValueDate == null)
{
return CurrentPaymentObject.ValueDate;
}
return dtValueDate;
}
set
{
dtValueDate = value;
if (value != null)
{
CurrentPaymentObject.ValueDate = (DateTime)value;
}
}
}

No comments:

Post a Comment