Search code examples
wpfdata-bindingcustom-controlscontentproperty

Custom control ContentProperty DataBinding


I'm running in a issue while trying to use dependency properties in objects which are parts of a collection, inside acustom control, collection identified with the "ContentProperty" attribute. Ok, that's quite unclear. Here is sample of my custom control :

Here is my custom control basic definition :

[ContentProperty("SmarSearchScopes ")]
public class SmartSearchCc : Control
{
    List<SmartSearchScope> SmarSearchScopes {get;set;}
    (more code here)
}

Here is the basic definition of a SmartSearchScope object :

public class SmartSearchScope : DependencyObject
{
    public static readonly DependencyProperty ViewProperty =DependencyProperty.Register("View", typeof (ICollectionView), typeof (SmartSearchScope),new UIPropertyMetadata(null,OnViewChanged));

    public static readonly DependencyProperty FilterColumnsProperty =DependencyProperty.Register("FilterColumns", typeof (IEnumerable<ColumnBase>), typeof (SmartSearchScope),new UIPropertyMetadata(null, OnFilterColumnsChanged));
    public ICollectionView View
    {
        get { return (ICollectionView) GetValue(ViewProperty); }
        set { SetValue(ViewProperty, value); }
    }

    public IEnumerable<ColumnBase> FilterColumns
    {
        get { return (IEnumerable<ColumnBase>) GetValue(FilterColumnsProperty); }
        set { SetValue(FilterColumnsProperty, value); }
    }
    (more code here)
}

All that for what ? Being able to pass a collection of SmartSearchScope objects via XAML like so :

<SmartSearch:SmartSearchCc HorizontalAlignment="Stretch" Grid.Row="0" >
    <SmartSearch:SmartSearchScope  FilterColumns="{Binding ElementName=CcyPairsConfigBlotter, Path=Columns}" View ="{Binding ElementName=CcyPairsConfigBlotter, Path=ItemsSource}"/>
    <SmartSearch:SmartSearchScope FilterColumns="{Binding ElementName=ClientConfigBlotter, Path=Columns}" View ="{Binding ElementName=ClientConfigBlotter, Path=ItemsSource}"/>
</SmartSearch:SmartSearchCc>

'ClientConfigBlotter' and 'CcyPairsConfigBlotter' are just two ItemsControls which expose a 'Columns' and an 'ItemSource' d-property.

The problem here is that althought my 2 SmartSearchScope objects gets instantiated, the databinding on the "View" and "FilterColumns" d-properties is not made and I never go througth the the associated callbacks.

In addition, here is the output error message I got when creating the custom control.

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Columns; DataItem=null; target element is 'SmartSearchScope' (HashCode=56862858); target property is 'FilterColumns' (type 'IEnumerable`1')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ItemsSource; DataItem=null; target element is 'SmartSearchScope' (HashCode=56862858); target property is 'View' (type 'ICollectionView')

This is obvious that I'm missing something but I can't find what.

I must say that, in a previous version of that control, these 2 problematic d-properties where SmartSearchCc properties and that all worked just fine.

Thanks for your help :)

--bruno


Solution

  • I had a similar problem here: Bindings on child dependency object of usercontrol not working

    The reason the binding doesn't work is because DependencyObjects don't have a DataContext property. In my case I changed them to inherit from FrameworkElement which solved the problem.

    Although as someone else has mentioned, changing the parent control to an ItemsControl could simplify things.