Search code examples
c#.netwpfdatagrid

Change between DataGrids CellTemplate and EditingCellTemplate on button click inside EditingCellTemplate


I am using a DataGrid and on a button click I want to be able to change between the CellTemplate and the EditingCellTemplate of the DataGrid Column.

Shows the DataGrid enter image description here

On load, the DataGrid shows the CellTemplate with the Permission Level.

When the user double clicks inside a Permission Level Cell the template changes to the EditingCellTemplate and a ItemsControl of buttons appears.

Shows the buttons enter image description here

When the user presses one of these buttons, Admin, Read or Write I want the Permission Level Template to display the CellTemplate just showing the text and not the EditingCellTemplate. I've thought about using a behaviour but unsure how it would work. Both of my CellTemplates are in a resource dictionary.

CellTemplate which shows the text

<DataTemplate x:Key="PermissionTemplate">
    <Border>
        <Label  Content="{Binding Path=PermissionLevel.Access}" />
    </Border>
</DataTemplate>

Editing cell template

<DataTemplate x:Key="EditingPermissionTemplate">
    <Border>
        <UniformGrid Rows="1" Columns="1">
                <ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=DataContext.AllPermissionLevels}" HorizontalContentAlignment="Stretch">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <Button Style="{StaticResource BaseButtonStyle}"
                                    Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=DataContext.UpdatePermissionCommand}"
                                        CommandParameter="{Binding}" >
                                    <TextBlock TextWrapping="Wrap" Text="{Binding Path=Access}" />
                                </Button>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
        </UniformGrid>
    </Border>
</DataTemplate>

DataGrid

<DataGrid ItemsSource="{Binding Path=AllUsersModules}" SelectedItem="{Binding Path=SelectedUsersModule}" 
                      Style="{StaticResource BaseDataGridStyle}" SelectionUnit="FullRow">
                <DataGrid.CellStyle>
                    <Style TargetType="{x:Type DataGridCell}">
                        <Setter Property="Background" Value="{StaticResource WhiteColorBrush}" />
                        <Setter Property="Foreground" Value="Black" />
                        <Style.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Background" Value="Transparent" />
                                <Setter Property="BorderBrush" Value="Orange" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </DataGrid.CellStyle>

                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="Module" HeaderStyle="{StaticResource DataGridColumnHeaderStyle}" Width="*" 
                                            CellTemplate="{StaticResource ModuleTemplate}"/>
                    <DataGridTemplateColumn Header="Permission Level" HeaderStyle="{StaticResource DataGridColumnHeaderStyle}" Width="*" 
                                            CellTemplate="{StaticResource PermissionTemplate}" 
                                            CellEditingTemplate="{StaticResource EditingPermissionTemplate}"/>
                </DataGrid.Columns>
            </DataGrid>

Solution

  • If you want to exit the edit mode when the Button is clicked, you could hook up a Click event handler that calls the CancelEdit() method of the DataGrid. Here is how to do this in a ResourceDictionary.

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        DataGrid dataGrid = FindParent<DataGrid>((Button)sender);
        if (dataGrid != null)
            dataGrid.CancelEdit();
    }
    
    private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
    {
        var parent = VisualTreeHelper.GetParent(dependencyObject);
    
        if (parent == null) return null;
    
        var parentT = parent as T;
        return parentT ?? FindParent<T>(parent);
    }