RAM
RAM

Reputation: 485

How do I change the DataTemplate while adding a new row to a DataGrid (for the new row only)

I need to show a DataGrid of that hides some sensitive information until the user actively requests it. I've construct the columns thus:

<DataGrid.Columns>
<DataGridTextColumn Header="User Name" Binding="{Binding UserName}" IsReadOnly="False" MinWidth="90"/>
<DataGridTemplateColumn Header="Password" IsReadOnly="False" MinWidth="90">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Content="Show"                                              
        Command="{Binding Path=DataContext.ShowPassword, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
        CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridCheckBoxColumn Header="Owner Only" Binding="{Binding OwnerOnly}" IsReadOnly="{Binding IsOwner, Converter={StaticResource InverseBooleanConverter}}" MinWidth="90"/>
<DataGridCheckBoxColumn Header="Active" Binding="{Binding Active}" IsReadOnly="False" MinWidth="90"/>
<DataGridTextColumn Header="Created" Binding="{Binding Created, StringFormat=\{0:dd.MM.yyyy HH:mm\}}" IsReadOnly="True" MinWidth="90"/>
<DataGridTextColumn Header="Superseded" Binding="{Binding Superseded, StringFormat=\{0:dd.MM.yyyy HH:mm\}}" IsReadOnly="True" MinWidth="90"/>

Which produces this:

enter image description here

When the user clicks on the Show button they are shown another view which audits the access and allows them to change the password.

The only problem I have is that I want to allow them to add new rows. When they do so they can't specify the password because that column is a button not a text field.

Question: is there anyway of changing that button on the 'new row' to be a TextBox?

Environment: MVVM with nothing in the code behind files. I don't mind putting some stuff in the code behind if that's the only way.

Thanks

SOLUTION

The accepted answer gave me 90 % of what I needed but I had to add a second data trigger...

<ContentControl>
    <ContentControl.Resources>
        <Button x:Key="btn" Content="Show"                                              
Command="{Binding Path=DataContext.ShowPassword, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"/>
    </ContentControl.Resources>
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Setter Property="Content" Value="{StaticResource btn}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Password}" Value="{x:Null}">
                        <Setter Property="Content">
                            <Setter.Value>
                                <TextBox />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="{x:Static CollectionView.NewItemPlaceholder}">
                        <Setter Property="Content">
                            <Setter.Value>
                                <TextBox />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
    </ContentControl.Style>
</ContentControl>

Upvotes: 1

Views: 459

Answers (1)

mm8
mm8

Reputation: 169200

You could use a ContentControl that binds to the parent DataContext and displays a TextBox if it is a NewItemPlaceholder. Something like this:

<DataGridTemplateColumn Header="Password" IsReadOnly="False" MinWidth="90">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ContentControl>
                <ContentControl.Resources>
                    <Button x:Key="btn" Content="Show"                                              
                                        Command="{Binding Path=DataContext.ShowPassword, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
                                        CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"/>
                </ContentControl.Resources>
                <ContentControl.Style>
                    <Style TargetType="ContentControl">
                        <Setter Property="Content" Value="{StaticResource btn}" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="{x:Static CollectionView.NewItemPlaceholder}">
                                <Setter Property="Content">
                                    <Setter.Value>
                                        <TextBox />
                                    </Setter.Value>
                                </Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Upvotes: 1

Related Questions