Accessing control between DataGridCells, dynamic c

2019-01-29 09:40发布

问题:

I have a DataGrid that two of its columns are ComboBoxes (one contains few but not this is the problem).

I want, that when the user changes the first Combo's value, the ComboBox in the other column should bind to a property of its (this property is a collection). Say the First ComboBox is Category, I want that when the user changes its value, the other CB is populated with the values of (first combo's selected category).Vendors.

How should I do it, I don't use MVVM, just simple WPF. I don't know what should be the right way to implement it, I hope I started it right.

I think, if I could get the other ComboBox (which is located in a different DataGridCell) from the first's SelectionChangeHandler that would be the best, because then I can reset its source on each selection change of the first one. Note that I have the capability of reaching the current (the first's) DataGridCell, I am just looking for an efficient way to access the right DataGridCell sibling and then get its child (second) combo.

Also note that the selected category should vary from row to row, and the second ComboBox should depend on this row's category.
I actually tried to implement it so that the CollectionViewSource.Source is bound to the current item (i.e. the row's DataContext) but it doesn't seem to work.
I prefer to set the second combo's CollectionViewSource (VendorsCollection) thru an Action trigger or handler at the 1st ComboBox's SelectionChange.

The other ComboBoxes in that field don't seem to make a problem as they're all bound to each other, I might use CollectionViewSource.Filter, anyway it's not a problem to access them as they are simple siblings, not like the first one which is a distant cousin located deep in another DataGridCell.

Here is what is what I tried so far:

<DataGrid>
    <DataGrid.Resources>
        <CollectionViewSource x:Key="CategoriesCollection" Source="{Binding Context.CategoriesList, Source={x:Static Application.Current}, IsAsync=True}" />
    </DataGrid.Resources>

    <DataGrid.Columns>

        <DataGridTemplateColumn Header="Category">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock DataContext="{Binding Category}" Text="{Binding Title}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <!--This is the first ComboBox-->
                    <ComboBox
                                IsSynchronizedWithCurrentItem="False"
                                ItemsSource="{Binding Source={StaticResource CategoriesCollection}}"
                                DisplayMemberPath="Title"
                                SelectionChanged="cbCategories_SelectionChanged"
                                SelectedItem="{Binding Category}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>

        <DataGridTemplateColumn Header="Style">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock DataContext="{Binding Finish.Style.Vendor}" Text="{Binding Contact.Title}"/>
                        <TextBlock DataContext="{Binding Finish.Style}" Text="{Binding Title}"/>
                        <TextBlock Text="{Binding Finish.Title}"/>
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel.Resources>
                            <!--I want, that when the user selects a value in the first ComboBox,
                    the VendorsCollection below should be populated with the selected Category.Vendors,
                    or alternatively current row's data item.Category.Vendors,
                    I just donno how to access current row from these resources.-->
                            <CollectionViewSource x:Key="VendorsCollection" Source="{Binding Vendors, Source={StaticResource CategoriesCollection}}" />
                            <CollectionViewSource x:Key="StylesCollection" Source="{Binding Styles, Source={StaticResource VendorsCollection}}" />
                            <CollectionViewSource x:Key="FinishesCollection" Source="{Binding Finishes, Source={StaticResource StylesCollection}}" />
                        </StackPanel.Resources>
                        <ComboBox                                                       
                                    IsSynchronizedWithCurrentItem="True"
                                    ItemsSource="{Binding Source={StaticResource VendorsCollection}}"
                                    SelectedItem="{Binding Finish.Style.Vendor}"
                                    DisplayMemberPath="Contact.Title"/>
                        <ComboBox
                                    IsSynchronizedWithCurrentItem="True"
                                    ItemsSource="{Binding Source={StaticResource StylesCollection}}"
                                    SelectedItem="{Binding Finish.Style}"
                                    DisplayMemberPath="Title"/>
                        <ComboBox
                                    IsSynchronizedWithCurrentItem="True"
                                    ItemsSource="{Binding Source={StaticResource FinishesCollection}}"
                                    SelectedItem="{Binding Finish}"
                                    DisplayMemberPath="Title"/>
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>

    </DataGrid.Columns>
</DataGrid>

回答1:

I just came across your questions. Did you get your problem resolved? I think your question is similar to this one I got. Hope the solution there helps you too.