1

I`m writing a new control containing three DataGrid's (DG_Top, DG_Center, DG_Bottom).

When trying to set the data for this control nothing happens. The ContextProperties (see below) are filled, but the data is not displayed.

In the UserControl (XGrid) I`ve created some properties to manage the DataBindings:

    public static readonly DependencyProperty ItemsSource_TopProperty = DependencyProperty.Register("ItemsSource_Top", typeof(IEnumerable), typeof(XGrid));
    public static readonly DependencyProperty ItemsSource_CenterProperty = DependencyProperty.Register("ItemsSource_Center", typeof(IEnumerable), typeof(XGrid));
    public static readonly DependencyProperty ItemsSource_BottomProperty = DependencyProperty.Register("ItemsSource_Bottom", typeof(IEnumerable), typeof(XGrid));
    public static readonly DependencyProperty DataContext_TopProperty = DependencyProperty.Register("DataContext_Top", typeof(object), typeof(XGrid));
    public static readonly DependencyProperty DataContext_CenterProperty = DependencyProperty.Register("DataContext_Center", typeof(object), typeof(XGrid));
    public static readonly DependencyProperty DataContext_BottomProperty = DependencyProperty.Register("DataContext_Bottom", typeof(object), typeof(XGrid));


    public IEnumerable ItemsSource_Top
    {
        get { return (IEnumerable)GetValue(ItemsSource_TopProperty); }
        set
        {
            SetValue(ItemsSource_TopProperty, value);
            OnPropertyChanged();
        }
    }
    public IEnumerable ItemsSource_Center...
    public IEnumerable ItemsSource_Bottom...

    public object DataContext_Top
    {
        get { return (object)GetValue(DataContext_TopProperty); }
        set
        {
            SetValue(DataContext_TopProperty, value);
            OnPropertyChanged();
        }
    }

    public object DataContext_Center...
    public object DataContext_Bottom...

The binding in the XGrid.xaml is the following:

    <UserControl x:Class="WPF.XGrid"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         x:Name="control">
 <StackPanel>
    <DataGrid ItemsSource="{Binding ItemsSource_Top, ElementName=control}"
              DataContext="{Binding DataContext_Top, ElementName=control}"  
...

I´m using the XGrid control as follows (in xaml):

<iw:XGrid x:Name="XG_Test" ItemsSource_Center="{Binding}"  />

And in the .cs file:

DataTable dt = new DataTable();
dt.Columns.Add("TEST");
dt.Rows.Add(new string[] { "" });
XG_Test.DataContext_Center = dt.DefaultView;

Can anybody tell me why the binding isn't working? THANKS!


-------EDIT 1-------

Visual Studio Output doesn't say anything about an error

This is what snoop says for the internal DataGrid (DG_Center)

5
  • Check the Output tab of Visual Studio, or use a tool like Snoop to examine the bound properties. You should be able to see the actual Binding error that way, and know what's really failing. Commented Jun 30, 2015 at 9:01
  • But other than that... Are you setting the three DataContext_x properties? And are you sure the ItemsSource you want to set is in that DataContext? Because in your example, you're setting ItemsSource_Center but not DataContext_Center, which will default to null and so your {Binding} will bind to nothing. Commented Jun 30, 2015 at 9:03
  • @almulo please see EDIT 1 I'm setting the DataContext in the .cs file (right above EDIT 1) => XG_Test.DataContext_Center = dt.DefaultView; Commented Jun 30, 2015 at 9:07
  • 1
    Ok, I think I know where the problem is. Your DataGrid's ItemsSource Binding is not taking into account the DataGrid DataContext, but is instead searching for its value in the XGrid control's DataContext. Commented Jun 30, 2015 at 9:19
  • @almulo Yeah, you're right, just tested it setting XG_Test.DataContext = dt.DefaultView; (Shows me the data in the DG_Center) But how can I get the DataGrid to use it's own Context? Commented Jun 30, 2015 at 9:24

1 Answer 1

1

Ok, I think I know where the problem is. Your DataGrid's ItemsSource Binding is not taking into account the DataGrid DataContext, but is instead searching for its value in the XGrid control's DataContext.

You have to make sure you're using the DataContext you want, doing something like this:

<iw:XGrid x:Name="XG_Test" 
          ItemsSource_Center="{Binding DataContext_Center.DefaultView,
                                       RelativeSource={RelativeSource Mode=Self}}"  />

But this kinda defeats the purpose of what you were trying to achieve, I guess...

EDIT: I've found another way that could make your original Bindings work as intended. It requires that you modify the UserControl's code-behind and create the ItemsSource bindings from there instead of doing it from XAML.

I'll take the "top" DataGrid as example.

  • First of all, give names to the DataGrids inside your UserControl, and remove the ItemsSource binding:

    <DataGrid x:Name="DataGrid_Top"
              DataContext="{Binding DataContext_Top, ElementName=control}" 
              ... /> 
    
  • Then, declare a property changed callback for your ItemsSource DependencyProperties:

    public static readonly DependencyProperty ItemsSource_TopProperty = 
        DependencyProperty.Register("ItemsSource_Top", typeof(IEnumerable), 
        typeof(XGrid), new PropertyMetadata(null, OnItemsSource_TopPropertyChanged));
    
  • In that callback you'll create the Binding, but in a different than usual way...

    private static void OnItemsSource_TopPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var control = sender as XGrid;
        var binding = BindingOperations.GetBindingBase(control, XGrid.ItemsSource_TopProperty);
        DataGrid_Top.SetBinding(DataGrid.ItemsSourceProperty, binding);
    }
    

And that's it... You're kinda "copying" the Binding from the DependencyProperty and into the ItemsSource property.

You can then change the XAML again to your original example, and it should work.

<iw:XGrid x:Name="XG_Test" ItemsSource_Center="{Binding}"  />
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! This works perfectly! Maybe I can find another way round this to keep the syntax smooth but for the first it's the solution I was looking for
Glad it helped :) I may give it another thought later, I'll write back if I find a better way

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.