Notes on Software

Using BindingGroup in custom controls

Posted by K. M. on September 25, 2008

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.

private void SetValueBinding()
{
    
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.

private BindingGroup GetParentBindingGroup()
{
    
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

private void SetValueBinding()
{
    
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);
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: