I understand you can make the whole DataGrid or a whole column readyonly (IsReadOnly = true). However, at cell level this property is ready only. But I do need this level of granularity. There is blog about adding IsReadOnly to a row by changing the source code in old days when DataGrid was public domain, but now I don't have source code for DataGrid. What's workaround?
Making cell disabled (IsEnabled=false) almost meets my need. But the problem is that you can't even click the disabled cell to select the row (I have full row selection mode).
EDIT: Since nobody has responded to this question, so I guess it's not an easy fix. Here is a possible workaround: Make the cell uneditable. The only problem is that clicking the cell doesn't select the row. I just noticed that MouseDown or MouseUp event of the DataGrid is still fired when the disabled cell is clicked. In this event handler, if I could figure out the row it clicked, I could select the row programmatically. However, I couldn't figure out how to find the underlying row from DataGrid.InputHitTest
. Can somebody please give me some tip?
I've encountered the same problem, the cell should be read-only in some rows but not in the others. Here is a workaround solution:
The idea is to dynamically switch the CellEditingTemplate
between two templates, one is the same as the one in the CellTemplate
, the other is for editing. This makes the edit mode acts exactly the same as the non-editing cell although it is in edit mode.
The following is some sample code for doing this, notice that this approach requires DataGridTemplateColumn
:
First, define two templates for read-only and editing cells:
<DataGrid>
<DataGrid.Resources>
<!-- the non-editing cell -->
<DataTemplate x:Key="ReadonlyCellTemplate">
<TextBlock Text="{Binding MyCellValue}" />
</DataTemplate>
<!-- the editing cell -->
<DataTemplate x:Key="EditableCellTemplate">
<TextBox Text="{Binding MyCellValue}" />
</DataTemplate>
</DataGrid.Resources>
</DataGrid>
Then define a data template with additional ContentPresenter
layer and use Trigger
to switch the ContentTemplate
of the ContentPresenter
, so the above two templates can be switched dynamically by the IsEditable
binding:
<DataGridTemplateColumn CellTemplate="{StaticResource ReadonlyCellTemplate}">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<!-- the additional layer of content presenter -->
<ContentPresenter x:Name="Presenter" Content="{Binding}" ContentTemplate="{StaticResource ReadonlyCellTemplate}" />
<DataTemplate.Triggers>
<!-- dynamically switch the content template by IsEditable binding -->
<DataTrigger Binding="{Binding IsEditable}" Value="True">
<Setter TargetName="Presenter" Property="ContentTemplate" Value="{StaticResource EditableCellTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
HTH