I would use a DataTrigger
which toggles the value of a property like TextBox.IsReadOnly
based on if the Department is equal to "Retail" or not
<Style ...>
<!-- Set Default -->
<Setter Property="IsReadOnly" Value="True" />
<Style.Triggers>
<DataTrigger Binding="{Binding Department}" Value="Retail">
<Setter Property="IsReadOnly" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
If you don't need any other editing in your DataGrid, it would be easiest to set IsReadOnly="True"
on your DataGrid
to disable editing entirely, and set this style on the TextBox
in your DataGridTemplateColumn
. This would get rid of a lot of your extra XAML code, like IsReadOnly="True"
<DataGrid ItemsSource="{Binding Path=MyTypeCollection}"
AutoGenerateColumns="False"
IsReadOnly="True">
<!-- This could also go in Window.Resources, UserControl.Resources, etc -->
<DataGrid.Resources>
<Style x:Key="SalesTextBoxStyle" TargetType="{x:Type TextBox}">
<!-- Set Default -->
<Setter Property="IsReadOnly" Value="True" />
<Style.Triggers>
<DataTrigger Binding="{Binding Department}" Value="Retail">
<Setter Property="IsReadOnly" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
<DataGridTextColumn Header="Department" Binding="{Binding Path=Department}" />
<DataGridTemplateColumn Header="Sales">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Sales}"
Style="{StaticResource SalesTextBoxStyle}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
If you do need the default DataGrid editing functionality, you could still use the same thing, but you'd only need a single TextBox
/TextBlock
in your DataTemplate
instead of the StackPanel
and multiple objects.
And if you really want it to display an actual TextBlock
instead of a TextBox
when the user doesn't have the ability to edit, you can use a ContentControl
and toggle it's ContentTemplate
property with a DataTrigger
<DataGrid.Resources>
<DataTemplate x:Key="TextBoxTemplate">
<TextBox Text="{Binding Path=.}" />
</DataTemplate>
</DataGrid.Resources>
...
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl x:Name="salesControl" Content="{Binding Sales}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Department}" Value="Retail">
<Setter TargetName="salesControl"
Property="ContentTemplate"
Value="{StaticResource TextBoxTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>