Search code examples
c#wpfwpfdatagrid

WPF- Add change event to autogenerated DataGridComboBoxColumn


I have a datagrid and in the DataGrid.AutoGeneratingColumn Event I change some of the columns to DataGridComboBoxColumns.

At the same time I also want to add a selection changed event to that new combobox, but can't figure out how to get access to the combobox control within the DataGridComboBoxColumn.

    private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        var cb = new DataGridComboBoxColumn();
        switch (e.PropertyName)
        {
            case "name":

                using (Entities context = new Entities())
                {
                    List<object> fNames = (from x in context.view
                        select new object {objectname = x.objectname}).ToList<object>();

                    cb.Header = "xxx";
                    cb.ItemsSource = xxx;
                    cb.SelectedItemBinding = new Binding("xxx");
                    e.Column = cb;

                    //Get reference to combobox in this new column
                    //Add event to it
                    //?????

                }
                break;
            //more ....
        }
    }

Solution

  • You cannot access ComboBox instance from DataGrid.AutoGeneratingColumn event handler, because ComBox is created only when a cell from that column goes into edit mode and new ComboBox instance is created every time that cell goes into edit mode.

    Here is a sample code how to do what you want via DataGridComboBoxColumn.EditingElementStyle property by setting EventSetter for Selector.SelectionChangedEvent (ComboBox inherits from Selector):

    private void dgGrid_AutogeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        switch (e.PropertyName)
        {
            case "name":
    
                var cb = new DataGridComboBoxColumn();
    
                // Old...
                cb.Header = "Name";
                cb.ItemsSource = new List<string>() { "Option1", "Option2", "Option3" };
                cb.SelectedItemBinding = new Binding("name");
    
                // NEW
                cb.EditingElementStyle = new Style(typeof(ComboBox))
                {
                    Setters =
                    {
                        new EventSetter(Selector.SelectionChangedEvent, new SelectionChangedEventHandler(OnComboBoxSelectionChanged))
                    }
                };
    
                e.Column = cb;
                break;
        }
    }
    
    private static void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // We must check that both RemovedItems and AddedItems are not empty,
        // because this event also fires when ComboBox is initialized (when entering edit mode), but then RemovedItems is empty.
        if (e.RemovedItems.Count > 0 && e.AddedItems.Count > 0)
        {
            var newlySelectedName = (string)e.AddedItems[0];
        }
    }