WPF DataGrid: DataGridComboxBox ItemsSource Binding to a Collection of Collections

北城以北 提交于 2019-11-27 07:01:35

Firstly, this should be easy... secondly, why are you building (and binding) columns in C#? Eek.

XAML (I'm using a regular grid because I'm lazy):

<ListView Name="MyListView">
    <ListView.View>
        <GridView>

            <GridView.Columns>

                <GridViewColumn DisplayMemberBinding="{Binding Operation}" />

                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Choices}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

            </GridView.Columns>

        </GridView>
    </ListView.View>
</ListView>

C#:

void Window1_Loaded(object sender, RoutedEventArgs e)
{
    var dahList = new List<StatsOperation>();

    dahList.Add(new StatsOperation
    {
        Operation = "Op A",
        Choices = new string[] { "One", "Two", "Three" },
    });

    dahList.Add(new StatsOperation
    {
        Operation = "Op B",
        Choices = new string[] { "4", "5", "6" },
    });

    this.MyListView.ItemsSource = dahList;
}

The Results:

WPF grid with dynamic combo box choices http://www.singingeels.com/Articles/Articles/UserImage.aspx?ImageID=b1e3f880-c278-4d2b-bcc2-8ad390591200

I think the mistake is in how you've done your binding. When you define a column, the binding is related to the object that is represented by a particular row. So as I understand, you have a StatsOperation for each row, so the TextBox column is bound to operation, which is how you have it, and the ComboBox column ItemsSource should be bound to a Collection. Right now it looks like it's bound to a Collection<Collection<string>>.

I've not defined columns in code-behind before so here is an example in XAML. I've found ComboBoxColumn can be tricky sometimes so i've shown how you can have a combobox in the column by using either a TemplateColumn or a ComboBoxColumn. I've copy pasted from my own code so just replace 'dg' with 'WPFToolkit' in your case:

<dg:DataGrid
      ...
      ...>
      <dg:DataGrid.Columns>
            <dg:DataGridTextColumn Binding="{Binding Operation}" CanUserReorder="True" CanUserResize="True" Header="Operation" />
            <dg:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" Header="Template Column">
                <dg:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Data}" SelectedItem="{Binding Operation}" />
                    </DataTemplate>
                </dg:DataGridTemplateColumn.CellTemplate>
            </dg:DataGridTemplateColumn>
            <dg:DataGridComboBoxColumn
                Header="ComboBox Column"                                                                                    
                 SelectedValueBinding="{Binding Operation}"                     
                 SelectedItemBinding="{Binding Operation}">
                <dg:DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                    </Style>
                </dg:DataGridComboBoxColumn.ElementStyle>
                <dg:DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                        <Setter Property="IsDropDownOpen" Value="True" />
                    </Style>
                </dg:DataGridComboBoxColumn.EditingElementStyle>
            </dg:DataGridComboBoxColumn>
      </dg:DataGrid.Columns>

</dg:DataGrid>

I'm assuming that Operation is the selected item, Data is the items to select from, and that your DataGrid is bound to a collection of StatsOperation. Good luck!

To fix your ItemsSource Binding Error use the form:

BindingOperations.SetBinding(new DataGridComboBoxColumn(), DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Data"));

You obviously can't do this in the intializer so you'll have to move your declarations around a bit but that should take care of that error in your update.

EDIT I'm sorry, I'm little slow at midnights :). Here is an updated answer. It looks like great article from Vincent Sibal WPF DataGrid - DataGridComboBoxColumn v1 Intro answers your question. Does it?

Partial - I think there is a confusion in what you are saying. You said you need a collection of collection of strings in each row so that the combo box could show different strings for different rows. However, for a combo box to show a set of strings, you only need a collection of strings, per row, not a collection of collection of strings.

Now since you need the collection of strings per row you might be thinking that you would need collection of collection of strings.

Is my understanding of your question correct? If so, then your mention of collection of collection of strings is wrong.

What you actually need is collection of StatOperations in which each StatOperation should have a collection of strings. This is exactly how you had as shown in your classes above.

To make progress, I suggest you edit your question and point out where exactly you were stuck after fixing the binding as suggested by AndyG.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!