C# – How to create DataSource dependency property on a wpf User Control


I have a user control that wraps a grid. I want to be able to set the underlying grid's data source, but through the user control, like this:

<my:CustomGrid DataSource="{Binding Path=CollectionView}" />

I have set this up in the grid like this:

    private static readonly DependencyProperty DataSourceProperty 
        = DependencyProperty.Register("DataSource", typeof(IEnumerable), typeof(CustomGrid));

    public IEnumerable DataSource
        get { return (IEnumerable)GetValue(DataSourceProperty); }
            SetValue(DataSourceProperty, value);
            underlyingGrid.DataSource = value;

But this doesn't work (it doesn't give me an error either). The data source is never set. What am I missing?

Best Solution

When WPF loads your control and encounters a DependencyProperty specified in XAML, it uses DependencyObject.SetValue to set the property value and not your class's property. This makes custom code in property setters which are dependency properties pretty much useless.

What you should do is override the OnPropertyChanged method (from DependencyObject):

    protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e ) {
        base.OnPropertyChanged( e );

        if( e.Property == DataSourceProperty ) {
            underlyingGrid.DataSource = e.NewValue;

Alternately you can specify a callback when you register the DependencyProperty:

    public static readonly DependencyProperty DataSourceProperty =
        DependencyProperty.Register( "DataSource", typeof( IEnumerable ), typeof( MyGridControl ), new PropertyMetadata( DataSourceChanged ) );

And do effectively the same as above in OnPropertyChanged in the callback:

    public static void DataSourceChanged( DependencyObject element, DependencyPropertyChangedEventArgs e ) {
        MyGridControl c = (MyGridControl) element;
        c.underlyingGrid.DataSource = e.NewValue;
Related Question