1

Is it possible to use 2 different collections to DataGrid?

Collection Days - Datagrid rows, Collection Headers - Datagrid headers.

ViewModel:

public class MonthViewModel : ViewModel
{
    public ObservableCollection<DayViewModel> Days { get; set; }
    public ObservableCollection<string> Headers { get; set; }

    public MonthViewModel()
    {
        Days = new ObservableCollection<DayViewModel>
        {
            new DayViewModel { Value1 = 1, Value2 = 2 },
            new DayViewModel { Value1 = 3, Value2 = 4 },
        };

        Headers = new ObservableCollection<string>
        {
            "Header1",
            "Header2"
        };
    }
}

public class DayViewModel : ViewModel
{
    private int _value1;
    public int Value1
    {
        get
        {
            return _value1;
        }
        set
        {
            _value1 = value;
            OnPropertyChanged();
        }
    }

    private int _value2;
    public int Value2
    {
        get
        {
            return _value2;
        }
        set
        {
            _value2 = value;
            OnPropertyChanged();
        }
    }
}

View:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Days}">

    <DataGrid.Columns>
        <DataGridTextColumn Header="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.Headers[0]}" Binding="{Binding Value1}"/>
        <DataGridTextColumn Header="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.Headers[1]}" Binding="{Binding Value2}"/>
    </DataGrid.Columns>

</DataGrid>

Error - Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''. BindingExpression:Path=DataContext.Headers[0]; DataItem=null; target element is 'DataGridTextColumn' (HashCode=7245576); target property is 'Header' (type 'Object')

What's the problem?

1 Answer 1

1

The problem is that your RelativeSource binding ends up looking for a property called "Headers" on your DataGrid's data context (which is set by ItemsSource, so is a collection of DayViewModel, clearly not something with a Headers property.

The smallest change would be to look at the Window's DataContext instead of the DataGrid's.

<DataGrid.Columns>
        <DataGridTextColumn Header="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Headers[0]}" Binding="{Binding Value1}"/>
        <DataGridTextColumn Header="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Headers[1]}" Binding="{Binding Value2}"/>
</DataGrid.Columns>

Given the declarative nature of XAML, and the fact that your headers probably shouldn't be changing at runtime, I would reconsider binding the "Header" text at all, but the above solution should fix your problem.

Sign up to request clarification or add additional context in comments.

Comments

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.