Home > Software design >  Update itemsource of a DataGridComboBoxColumn depending on another
Update itemsource of a DataGridComboBoxColumn depending on another

Time:09-17

I'm using a Datagrid with 2 DataGridComboBoxColumns and I'm trying to update the itemsource of the second column depending on the selected 'league' in the first column.

My xaml:

            <DataGrid Name="DataTable" ItemsSource="{Binding Data}" AutoGenerateColumns="false">
                <DataGrid.Columns>
                    <DataGridComboBoxColumn x:Name="DataTableLeague" Header="League"  DisplayMemberPath="League.Name" SelectedValuePath="League.Name" SelectedValueBinding="{Binding LeagueName}">
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="{x:Type ComboBox}">
                                <EventSetter Event="SelectionChanged" Handler="CmbLeague_SelectionChanged" />
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>
                    <DataGridComboBoxColumn x:Name="DataTableClub" Header="Club" DisplayMemberPath="Name" SelectedValuePath="Name" SelectedValueBinding="{Binding ClubName}"/>
                </DataGrid.Columns>
            </DataGrid>

code behind:

public Editor()
{
      InitializeComponent();
      DataContext = this;
      DataTableLeague.ItemsSource = Leagues;         
}

private void CmbLeague_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // ???
}

List<League> Leagues contains List<Clubs> and should only be used as a source. The selection is stored in an ObservableCollection named Data.

CodePudding user response:

Instead of handling an event, you could bind the ItemsSource of the second ComboBox to a source property of your data object and set it in the setter of the LeagueName property which is bound to the selected value of the first ComboBox.

Make sure that your data object implements the INotifyPropertyChanged interface and raise change notifications whenever the you set the source property for the ItemsSource property of the second ComboBox, e.g.:

public class DataItem : INotifyPropertyChanged
{
    private string _leagueName;
    public string LeagueName
    {
        get { return _leagueName; }
        set 
        { 
            _leagueName = value;
            NotifyPropertyChanged();

            Teams = ...;
        }
    }


    private IEnumerable<Team> _teams;
    public IEnumerable<Team> Teams
    {
        get { return _teams; }
        set { _teams = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}

XAML:

 <DataGridComboBoxColumn x:Name="DataTableClub" ItemsSource="{Binding Teams}" ... />

CodePudding user response:

while this seems to be a solid approach, i would like to see a solution using the CmbLeague_SelectionChanged event

Well, you could cast the DataContext of the ComboBox that gets passed to the event handler and then set the property:

private void CmbLeague_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox cmb = (ComboBox)sender;
    if (cmb.DataContext is DataItem dataItem)
    {
        dataItem.Teams = ...;
    }
}

You will still need to implement INotifyPropertyChanged in your data class though.

  • Related