Binding cascading combobox itemsource in wpf datag

2019-07-24 03:31发布

问题:

How to bind a 2nd dropdown based on first dropdown selected value of first dropdown using mvvm

Here is the class strcture

List<Location> Locations; //Application global cached data 
List<Room> Room; //Application global cached data 
class Location {LocationId, Name ....} 
class Room{RoomId, Name, LocationId...}

XAML

 <DataGridTemplateColumn Header="Property Name">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox Name="LocationsComboBox"
                  ItemsSource="{Binding Path=DataContext.Locations, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"                
                  DisplayMemberPath="Name" SelectedValuePath="Id"
                  SelectedValue="{Binding PropertyId, UpdateSourceTrigger=PropertyChanged}">
            </ComboBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<!--Room Number-->
<DataGridTemplateColumn Header="Room Number">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox Name="RoomComboBox"
                  ItemsSource="{Binding Path=DataContext.Rooms, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"               
                  DisplayMemberPath="RoomName" SelectedValuePath="RoomId"
                  SelectedValue="{Binding NewRoomId, UpdateSourceTrigger=PropertyChanged}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <i:InvokeCommandAction 
                            Command="{Binding DataContext.PropertyChangedCommand, 
                                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" 
                            CommandParameter="{Binding}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </ComboBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

回答1:

Did you use INotifypropertychanged ? you should implement INotifyPropertyChanged and change your child list when parent was changed



回答2:

I prefer Master Slave/Details way of combo box. U can find Here

But in your Case

The binding for Room ComboBox should be from Code Behind on the basis of selected LocationID.

the below binding

ItemsSource="{Binding Path=DataContext.Rooms..

should be something like this

ItemsSource="{Binding Path=DataContext.RoomsInSelectedLocation

and in ViewModel

iEnumerabe RoomsInSelectedLocation
{
return Rooms.where(r =>r.LocationId == SelectedLocationId);
}

evaluate this every time the Location Combo selected item changes.



回答3:

Use ObservableCollection<Room> instead of List (this will cause the second combobox to update when the first combo box changes the location which in turn causes the room collection to change.

Use ObservableCollection<Location> also. Your locations might not ever change, but this is simply good MVVM form.