How to make the contents of the DataGrid column (which is displayed as a TextBox) edited according to the ComboBox principle?

Prehistory : the application processes data from several almost identical tables, for this purpose a single basic show / process window is created, which uses a DataGrid with automatic creation of columns. In the markup (xaml), only a few trifles for the appearance and a pair of background and font color converters are defined. There are several buttons on the main application window that open the processing window, overriding the data source. Everything suited everyone - when clicking on a cell, it went into edit mode, then the completion event was caught, and so on.

Now, for one table, it was necessary to select data from a static list in one field (the use of ComboBox suggests itself), but I don’t want to abandon the autogeneration of columns - I don’t use markup, I want it programmatically. Therefore, from the base class of the processing window, I inherit a new class (it will be a new window), catch myGrid_AutoGeneratingColumn and in it I want to remake the desired column (recognize by name) in DataGridComboBoxColumn, so that when editing it is opened with a list.

Under the “hand” only the column we are looking for can change its properties, but it’s impossible to override its presentation style. Blackout Or am I trying in the wrong place?

  • Do you have the opportunity to write MCVE ? It is not entirely clear what exactly the problem is, since the method that you describe sounds logical. - user227049
  • it turned out to create a ComboBox; it turned out to be more difficult to establish in it the values ​​that came from the database. Therefore, I refused this method. - sergNN

2 answers 2

As an option, do not change the style of the column and delete and create a new one:

 public class ModelDG : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { var e = PropertyChanged; if (e != null) { e(this, new PropertyChangedEventArgs(propertyName)); } } public string Name { get; set; } public string ListName { get; set; } } public MainWindow() { InitializeComponent(); ObservableCollection<ModelDG> ListDG = new ObservableCollection<ModelDG>() { new ModelDG{ Name ="String1", ListName="ComboBox1"}, new ModelDG{ Name ="String2", ListName="ComboBox2"}, new ModelDG{ Name ="String3", ListName="ComboBox3"}, new ModelDG{ Name ="String4", ListName="ComboBox4"}, new ModelDG{ Name ="String5", ListName="ComboBox5"}, new ModelDG{ Name ="String6", ListName="ComboBox6"}, }; dgrid.ItemsSource = ListDG; } private void btn_Click(object sender, RoutedEventArgs e) { foreach(DataGridColumn col in dgrid.Columns) { if (col.DisplayIndex == 1) { DataGridComboBoxColumn columnCB = new DataGridComboBoxColumn(); columnCB.ItemsSource = new List<string> { "One","Two","Tree","Four" }; columnCB.Header = "ListNames"; dgrid.Columns.Add(columnCB); dgrid.Columns.Remove(col); break; } } } 
  • Thanks for the option. I think that the result is the same (being in the "DataGrid_AutoGeneratingColumn" I simply recognize my column and replace it with the new ComboBox so: args.Column = myDGCBC). The problem is that I lose the value that originally comes from the database! Those. The new ComboBox is present, but the value is not selected. How to be? - sergNN
  • It is necessary to keep what came from the base, and not to throw it away. And it’s better to use the MVVM approach - Andrey NOP

After spending a lot of time, I refused to auto-generate the speakers and did the manual markup:

  <DataGridTemplateColumn Header="Mapping" Width="110"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Mapping}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox Height="22" ItemsSource="{StaticResource MappingList}" SelectedValue="{Binding Mapping}" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> 

Now when editing, the ComboBox appears, then everything looks like a normal text field. But there was a related problem - how to check the selected (so-called new) value in the ComboBox? I use the DataGrid_CellEditEnding event, but I can't get to ComboBox !!! As a parameter, I get a DataGridCellEditEndingEventArgs e , but there is little joy in it - I see only unchanged data ...

  • You seem to have a SelectedValue binding to someone's property, why not track its change? - Andrei S.
  • Did not quite understand the answer - track the change of what? If the "Mapping" fields, then it is about it - I can not reach the selected new value, being in DataGrid_CellEditEnding. If there is another opportunity - grateful for any ideas. - sergNN
  • Well, look, SelectedValue = "{Binding Mapping}" means that the Mapping property will always have the value of the SelectedValue property and vice versa, right? That is, if you cannot get an object containing the Mapping property from the DataGrid_CellEditEnding handler, then you can try implementing the INotifyPropertyChanged interface for the type that contains Mapping - Andrei S.