15

I have 3 tables: Item - which is the DataContext - it has a navigation column Group Group - has a navigation column Category.

I want to have in the DataGrid both (Category & Group) columns and when I choose a category it should display in the group col only the Category.Groups.

Here is the code I am working on:

<tk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}">
    <tk:DataGrid.Columns>

        <!--Works-->
        <tk:DataGridComboBoxColumn                                        
            Header="Categroy" 
            DisplayMemberPath="Title"                    
            SelectedValuePath="CategoryId"
            SelectedValueBinding="{Binding Group.Category.CategoryId}"
            ItemsSource="{Binding Context.Categories, 
                Source={x:Static Application.Current}}"
        />


        <!--Look at these two things:-->

        <!--This does work-->
        <tk:DataGridTemplateColumn>
            <tk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ItemsControl
                        ItemsSource="{Binding Group.Category.Groups}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate DataType="{x:Type data:Group}">
                                <TextBlock Text="{Binding Title}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </DataTemplate>
            </tk:DataGridTemplateColumn.CellTemplate>
        </tk:DataGridTemplateColumn>

        <!--But this does NOT work, even it's the same source-->
        <!--Notice I even tried a dummy converter and doesnt reach there-->
        <tk:DataGridComboBoxColumn 
            Header="Group" 
            DisplayMemberPath="Title"
            SelectedValuePath="GroupId"
            ItemsSource="{Binding Group.Category.Groups,
                Converter={StaticResource DummyConverter}}"
            SelectedValueBinding="{Binding Group.GroupId}"
            />

    </tk:DataGrid.Columns>
</tk:DataGrid>

Update
Would you say the problem is that the ItemsSource property cannot be set to a non-static Binding? I suspect so because even I set the ItemsSource to {Binding} with the DummyConverter it doesn't stop in the converter; and in the Category ComboBox it works fine.

2 Answers 2

34

The columns in the datagrid don't have a datacontext, as they are never added to the visual tree. sound a bit weird but have a look at vince's blog, its got a good example of the visual layout. once the grid is drawn the cells have a data context and you can set the combo boxes items source in them using normal bindings (not static resources..)

You can access the combo box items source as such:

<dg:DataGridComboBoxColumn>
   <dg:DataGridComboBoxColumn.EditingElementStyle>
      <Style TargetType="ComboBox">
         <Setter Property="ItemsSource" Value="{Binding Path=MyBindingPath}" />
      </Style>
   </dg:DataGridComboBoxColumn.EditingElementStyle>
</dg:DataGridComboBoxColumn>

Have a look here and also here for some code. You will also need to set the items source for the non edting element as in this post

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

6 Comments

How to make it work for .NET 4.0 Datagrid? Vince's blog seems to be out-dated.
I don't think the datagrid's implementation of the ComboColumn changed in the .net 4 release
I used same approach, but datasource doesn't seems to bind the column. I am seeing empty combobox in DataGrid
Chuck a debugConverter on it and see if the bindings ever fire (wpftutorial.net/DebugDataBinding.html)
Shouldn't it also work just to target a particular ElementName that has a DataContext?
|
9

I was using MVVM and I wanted to bind the ItemSource of the column to a collection of objects in the window data context. I must have tried 10 different ways and nothing worked until I found this answer.

The trick is to define a CollectionViewSource outside the grid and then reference it inside the grid using StaticResource. For example,

<Window.Resources>
    <CollectionViewSource x:Key="ItemsCVS" Source="{Binding MyItems}" />
</Window.Resources>
<!-- ... -->
<DataGrid ItemsSource="{Binding MyRecords}">
    <DataGridComboBoxColumn Header="Column With Predefined Values"
                            ItemsSource="{Binding Source={StaticResource ItemsCVS}}"
                            SelectedValueBinding="{Binding MyItemId}"
                            SelectedValuePath="Id"
                            DisplayMemberPath="StatusCode" />
</DataGrid>

1 Comment

I think this decision is simpler than using proxy elements... Thanks!

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.