xamlwinui-3winuiwindows-community-toolkit

How to attach eventhandler to DataGrid Combobox Selection Changed


Using the DataGrid in the Community ToolKit. How can one bind an eventhandler to listen for a change in the DataGridComboBoxColumn?


Solution

  • Unfortunately, you can't. One way to achieve this is to use the DataGridTemplateColumn with a CheckBox in it.

    For example:

    *.xaml

    <toolkit:DataGrid.Columns>
        <toolkit:DataGridTemplateColumn Header="IsEnabled">
            <toolkit:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox
                        Loaded="ComboBox_Loaded"
                        SelectionChanged="ComboBox_SelectionChanged" />
                </DataTemplate>
            </toolkit:DataGridTemplateColumn.CellTemplate>
        </toolkit:DataGridTemplateColumn>
    </toolkit:DataGrid.Columns>
    

    then in code-behind you'll have:

    *.xaml.cs

    private void ComboBox_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
    {
        if (sender is not ComboBox comboBox)
        {
            return;
        }
    
        comboBox.ItemsSource = ComboBoxItems;
        comboBox.SelectedIndex = 0;
    }
    
    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"Selected item: {e.AddedItems.ToString()}");
    }
    

    UPDATE

    You can also create a custom DataGridComboBoxColumn:

    public class DataGridComboBoxColumnEx : DataGridComboBoxColumn
    {
        public event SelectionChangedEventHandler? SelectionChanged;
    
        protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
        {
            var comboBox = (ComboBox)base.GenerateEditingElement(cell, dataItem);
            
            comboBox.SelectionChanged -= ComboBox_SelectionChanged;
            comboBox.SelectionChanged += ComboBox_SelectionChanged;
            return comboBox;
        }
    
        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SelectionChanged?.Invoke(sender, e);
        }
    }
    

    Then use it like a plain DataGridComboBoxColumn:

    <local:DataGridComboBoxColumnEx
        SelectionChanged="ComboBox_SelectionChanged"
        ItemsSource="{x:Bind ComboBoxItems}"
        Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        Header="Enabled" />