1
votes

To explain my problem I did a small demo Application. I have a DataGrid with several TextColumns and a ComboBoxColumn - the Binding for the TextColumns works well, but not for the ComboBoxColumn.

The data comes from this simple Model:

public class Model
{
    public Model()
    {
        Text = "text";
        ComboText = "T2";
    }
    public string Text { get; set; }
    public string ComboText { get; set; }
}

My ViewModel has two Collections: a list of models to show in the Datagrid and a list of strings to show in the Combobox dropdown (this list should later be not static).

    public class MainWindowViewModel
{
    private ObservableCollection<Model> _model;
    public MainWindowViewModel()
    {
        _model = new ObservableCollection<Model>();
        _model.Add(new Model());
        ComboItems = new ObservableCollection<string>();
        ComboItems.Add("T1");
        ComboItems.Add("T2");
        ComboItems.Add("T3");
        ComboItems.Add("T4");
        ComboItems.Add("T5");
    }

    public ObservableCollection<Model> Models
    {
        get
        {
            return _model;
        }
    }

    public ObservableCollection<string> ComboItems
    { get; private set; }
}

In my view's Code Behind i only set the DataContext of the view to MainWindowView Model:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        DataContext = new ViewModels.MainWindowViewModel();
        InitializeComponent();
    }
}

I knew, I can set the ComboBox Itemssource here(witch works), but i can not access this class later from the ViewModel to update it.

I set the Itemssource of the Data Grid to Models and the Binding for the TextColumns is fine. But setting the ComboBoxColumns itemsource to DataContext.ComboItems (or just ComboItems) doesn't work.

<Window x:Class="TestCombobox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TestCombobox"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <DataGrid AutoGenerateColumns="False" Name="MyDataGrid" ItemsSource="{Binding Models}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="TextColumn" Binding="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>
            <DataGridComboBoxColumn Header="Combo" ItemsSource="{Binding DataContext.ComboItems}" SelectedValueBinding="{Binding ComboText}" DisplayMemberPath="{Binding ComboText}"/>
            <DataGridTemplateColumn Header="TemplateColumn">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding DataContext.ComboItems}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

Any solutions / ideas to solve this? Thanks for your help.

1

1 Answers

0
votes

You have to use RelativeSource:

<DataGrid AutoGenerateColumns="False" Name="MyDataGrid" ItemsSource="{Binding Models}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="TextColumn" Binding="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>
        <DataGridTemplateColumn Header="TemplateColumn">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding DataContext.ComboItems, 
                        RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Or ElementName:

<DataGrid AutoGenerateColumns="False" Name="MyDataGrid" ItemsSource="{Binding Models}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="TextColumn" Binding="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>
        <DataGridTemplateColumn Header="TemplateColumn">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding DataContext.ComboItems, 
                        ElementName=MyDataGrid}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>