0
votes

I'm using WPF DataGrid control with dynamic columns binding at run time.(DataGrid columns are dynamic)

Sample code is as below

.xaml is having below code

 <Style TargetType="ComboBox" x:Key="ComboBoxEditingStyle">
                <Setter Property="ItemsSource" Value="{Binding Path=DefinedFormatters}" />
                <Setter Property="IsDropDownOpen" Value="False" />
                <Setter Property="IsEditable" Value="True" />
                <Setter Property="SelectedValue" Value="Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=Name}"></TextBlock>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

.xaml.cs file is having below code,

 Binding theBinding  = new Binding();
 theBinding.Mode = BindingMode.TwoWay;
 theBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
 theBinding.ValidatesOnDataErrors = true;

 DataGridComboBoxColumn colSuggestionList = new DataGridComboBoxColumn();

 // theCollection is Collection<string>     
 colSuggestionList.ItemsSource = theCollection;


 colSuggestionList.SelectedValueBinding = theBinding;
 colSuggestionList.Visibility = Visibility.Visible;   
 colSuggestionList.EditingElementStyle = dgMainTemplate.FindResource("ComboBoxEditingStyle") as Style;
 // dgMainTemplate is wpf DataGrid                      
 dgMainTemplate.Columns.Add(colSuggestionList);

Column added properly, but I want to make this column as editable. User should be able to select either existing item from available list or enter a new value which is not exists in available list. Here EditingElementStyle will add editable combobox but items are not showing in combobox until user selects any item.

1
There is no direct way to do this. But you can checkout this link stackoverflow.com/questions/14257656/… - Aakanksha
You should use DataGridTemplateColumn 's CellTemplate and CellEditingTemplate to allow user to select a value in ComboBox or enter a free value in TextBox. - user1672994
@user1672994 its easy to handle at design time, but is it possible to add columns dynamically at run time ?using DataGridTemplateColumn 's CellTemplate - Kiran Desai
Rather than writing code like you're doing, the recommended way to do this sort of thing is to build xaml as a string and then xamlreader.parse it into UI. You can define templates you want to use for each scenario and substitute strings for binding variables, collections etc. social.technet.microsoft.com/wiki/contents/articles/… Not exactly what you're doing here, I didn't write them with exactly this in mind so the samples are to illustrate the approach rather than cut and paste. - Andy
By the way. Editing in a datagrid is rarely a good plan, in my experience. Almost always better to select a row and edit in a separate panel so the user is explicitly working with one row at a time. - Andy

1 Answers

0
votes

Finally I got solution to this problem, Modified code is as below,

 <Style x:Key="TextBlockComboBoxStyle" TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ComboBox}">
                            <Label Content="{TemplateBinding Text}" Style="{StaticResource {x:Type Label}}" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <Style TargetType="ComboBox" x:Key="ComboBoxEditingStyle">
                <Setter Property="ItemsSource" Value="{Binding Path=DefinedFormatters}" />
                <Setter Property="IsDropDownOpen" Value="False" />
                <Setter Property="IsEditable" Value="True" />
            </Style>

.cs code is,

 Binding theBinding  = new Binding();
 theBinding.Mode = BindingMode.TwoWay;
 theBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
 theBinding.ValidatesOnDataErrors = true;

 DataGridComboBoxColumn colSuggestionList = new DataGridComboBoxColumn();

 // theCollection is Collection<string>     
 colSuggestionList.ItemsSource = theCollection;


 colSuggestionList.SelectedValueBinding = theBinding;
 colSuggestionList.Visibility = Visibility.Visible;   
 colSuggestionList.EditingElementStyle = dgMainTemplate.FindResource("ComboBoxEditingStyle") as Style;

 colSuggestionList.EditingElementStyle = dgMainTemplate.FindResource("ComboBoxEditingStyle") as Style;
 colSuggestionList.ElementStyle = dgMainTemplate.FindResource("TextBlockComboBoxStyle") as Style;
 // dgMainTemplate is wpf DataGrid                      
 dgMainTemplate.Columns.Add(colSuggestionList);