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.