I have a WPF custom control to display and edit a double value. The control exposes a dependency property called Value, along with a Format, Converter and ConverterParameter properties. The control template has a TextBox whose Text property is bound to the Value property with a custom converter.
{
if (textbox == null) return;
textbox.SetBinding(TextBox.TextProperty, new Binding(“Value”)
{
Source = this,
Converter = new CustomConverter() { Converter = Converter, Format = Format },
ConverterParameter = ConverterParameter,
Mode = BindingMode.TwoWay,
ValidatesOnExceptions = true
});
}
(Here textbox is the instance of the TextBox that must be a part of the ControlTemplate, and the SetValueBinding method is called in the OnApplyTemplate override after obtaining the textbox instance)
This works well except for validation. If the user types in some text in the custom control that cannot be converted to a double, the Binding shown above fails. But this binding error does not participate in the validation mechanism (look at my earlier post on validation for a pattern for implementing validation). The solution is to find a BindingGroup on a parent of the custom control and add the BindingExpression to the BindingGroup.
{
FrameworkElement element = this;
while (element != null)
{
BindingGroup grp = element.BindingGroup;
if (grp != null)
return grp;
element = VisualTreeHelper.GetParent(element) as FrameworkElement;
}
return null;
}
This can now be used in the SetValueBinding method
{
if (textbox == null) return;
BindingGroup group = GetParentBindingGroup();
BindingExpressionBase expr =
BindingOperations.GetBindingExpressionBase(textbox, TextBox.TextProperty);
if (group != null && expr != null)
group.BindingExpressions.Remove(expr);
textbox.SetBinding(TextBox.TextProperty, new Binding(“Value”)
{
Source = this,
Converter = new CustomConverter() { Converter = Converter, Format = Format },
ConverterParameter = ConverterParameter,
Mode = BindingMode.TwoWay,
ValidatesOnExceptions = true
});
expr = BindingOperations.GetBindingExpressionBase(textbox, TextBox.TextProperty);
if (group != null)
group.BindingExpressions.Add(expr);
}