Search code examples
wpfdata-bindingdatagrid

Datagrid different control on same column and getting their values


I have managed to create a datagrid that contains different type of control on same column. However, I am not able to get the user input in these controls.

Item

public class Item
{
    /// <summary>
    /// item name
    /// </summary>
    public string ParameterName { get; set; }

    /// <summary>
    /// Control type
    /// </summary>
    public ControlType ControlType { get; set; }

    /// <summary>
    /// New item value
    /// </summary>
    public object ParameterValue { get; set; }

    /// <summary>
    /// Current item value
    /// </summary>
    public string CurrentParameterValue { get; set; }
}

ControlType

public enum ControlType
{
    TextBox,
    ComboBox,
    CheckBox,
    TextBlock
}

DataGrid

<DataGrid x:Name="dgridGeneral" ItemsSource="{Binding}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserResizeColumns="False" SelectionUnit="FullRow">
     <DataGrid.Columns>
         <DataGridTemplateColumn Header="Name" Width="200">
             <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <TextBlock Text="{Binding ParameterName}" Style="{StaticResource TextHeader}" />
                 </DataTemplate>
             </DataGridTemplateColumn.CellTemplate>
         </DataGridTemplateColumn>
         <DataGridTemplateColumn Header="New Value" Width="200">
             <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <ContentControl Content="{Binding}">
                         <ContentControl.Style>
                             <Style TargetType="ContentControl">
                                 <Style.Triggers>
                                     <DataTrigger Binding="{Binding ControlType}" Value="CheckBox">
                                         <Setter Property="ContentTemplate">
                                             <Setter.Value>
                                                 <DataTemplate>
                                                     <CheckBox IsChecked="{Binding ParameterValue, Mode=TwoWay}"/>
                                                 </DataTemplate>
                                             </Setter.Value>
                                         </Setter>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding ControlType}" Value="ComboBox">
                                            <Setter Property="ContentTemplate">
                                                <Setter.Value>
                                                    <DataTemplate>
                                                        <ComboBox ItemsSource="{Binding ComboBoxControlItemSource}" SelectedIndex="{Binding ParameterValue, Mode=TwoWay}" />
                                                    </DataTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding ControlType}" Value="TextBlock">
                                            <Setter Property="ContentTemplate">
                                                            <Setter.Value>
                                                <DataTemplate>
                                                    <TextBlock Text="{Binding ParameterValue}"/>
                                                </DataTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ControlType}" Value="TextBox">
                                        <Setter Property="ContentTemplate">
                                            <Setter.Value>
                                                <DataTemplate>
                                                    <TextBox Text="{Binding ParameterValue, Mode=TwoWay}" />
                                                </DataTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </ContentControl.Style>
                    </ContentControl>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Current Value" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding CurrentParameterValue}" Style="{StaticResource TextBodyNormal}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

I have also tried to add additional properties for different control types in Item class. For instance, a "Text" property for TextBox, a "IsCheck" property for CheckBox, a SelectedIndex property for ComboBox. However, I still was not able to obtain the user input.

How do I obtain the inputs from the user?


Solution

  • The ParameterValue property of the Item will be set if you set the UpdateSourceTrigger property of the bindings to PropertyChanged:

    <Style.Triggers>
        <DataTrigger Binding="{Binding ControlType}" Value="CheckBox">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <CheckBox Content="{Binding}" IsChecked="{Binding ParameterValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </DataTrigger>
        <DataTrigger Binding="{Binding ControlType}" Value="ComboBox">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding ComboBoxControlItemSource}" 
                                                                          SelectedIndex="{Binding ParameterValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </DataTrigger>
        <DataTrigger Binding="{Binding ControlType}" Value="TextBlock">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Text="{Binding ParameterValue}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </DataTrigger>
        <DataTrigger Binding="{Binding ControlType}" Value="TextBox">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBox Text="{Binding ParameterValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>