Search code examples
wpfdatagridtextboxdatagridtemplatecolumn

WPF: How to replace the TextBox of Datagrid used for Editing in a DataGridTextColumn


I haven't really found a decent solution for the following issue: when I edit some columns of a DataGrid in WPF/NetCore, I would like to use a customized Textbox or Control to that I can take various actions, like warning for duplicates, display similar entries or event prevent duplicates from completing, etc...

<DataGrid ItemsSource="{Binding lessonEntries}" AutoGenerateColumns="False" Grid.Column="0" Grid.Row="0" Margin="10" CanUserAddRows="True" CanUserDeleteRows="True" CanUserReorderColumns="False" CanUserSortColumns="True">

 <DataGrid.Columns>
        <DataGridTextColumn Header="{x:Static res:Strings.wndMainColNative}"    Binding="{Binding Native.Text}"  Width="*" />
        <DataGridTextColumn Header="{x:Static res:Strings.wndMainColForeign}"   Binding="{Binding Foreign.Text}" Width="*" />

        <!-- TEST -->
        <DataGridTemplateColumn Header="Test1" Width="*">
            <DataGridTemplateColumn.CellTemplate >
                <DataTemplate>
                    <TextBox Name="testBox" Text="{Binding Path=Foreign.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ></TextBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTextColumn Header="{x:Static res:Strings.wndMainColLvlSpeak}"  Binding="{Binding LevelSpeak.Level}"     IsReadOnly="False" />
        <DataGridTextColumn Header="{x:Static res:Strings.wndMainColWrite}"     Binding="{Binding LevelWrite.Level}"     IsReadOnly="False" />
        <DataGridTextColumn Header="{x:Static res:Strings.wndMainColListen}"    Binding="{Binding LevelListen.Level}"    IsReadOnly="False" />
    </DataGrid.Columns>

</DataGrid>

But I could not find how to replace the Text box.

Ultimatively I will pass settings to the Custom Control like list of allowed words, denied words, or existing words, and it will behave as specified.

The closest I found is using a DataGridTemplateColumn but it is always in edit mode while I need this only when editing a cell.

EDIT:

Somethimes the solution just ist there and you don't see it! Thanks to @Rekshino

Acutally TextBlock is the control to use for display mode, but the solution was using DataGridTemplateColumn:

<DataGridTemplateColumn Header="Test1" Width="*">
    <DataGridTemplateColumn.CellTemplate >
        <DataTemplate>
            <TextBlock Name="testBox" Text="{Binding Path=Foreign.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <StackPanel >
                <ComboBox SelectedItem="{Binding Path=Foreign.Text}"/>
            </StackPanel>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

Solution

  • You can use DataGridTemplateColumn.CellEditingTemplate for it:

    <DataGridTemplateColumn >
        <DataGridTemplateColumn Header="Test1" Width="*">
            <DataGridTemplateColumn.CellTemplate >
                <DataTemplate>
                    <TextBox Name="testBox" Text="{Binding Path=Foreign.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ></TextBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
                <StackPanel >
                    <ComboBox ItemsSource="{StaticResource YourListOfWords}" SelectedItem="{Binding Path=Foreign.Text}"/>
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>