Один из способов решения этой проблемы основан на коде в этом ответе:
Как сделать WPF DataGridCell ReadOnly?
Что означает переключение шаблона дляячейка с использованием источника данных.
В случае, если он каким-то образом осиротит, разметка оттуда:
<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>
и
<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>
Вам необходимо свойство, чтобы управлять этим дататригером.
Определить модель представления, которая будет представлять каждую строку (rowViewModel).
Это требует публичного свойства для каждого столбца.
Затем вам понадобится ваше новое свойство для этого источника данных, который покажет, будет ли это новая строка или нет. Назовите это IsNew (или как вы предпочитаете). Свяжите Itemssource с наблюдаемой коллекцией RowViewModel. Значение по умолчанию для IsNew должно быть истинным. Когда вы читаете старые данные из базы данных, установите IsNew в false.
Затем вам нужно применить этот подход ко всем столбцам, кроме вашего последнего.
Это будет довольно неуклюже, но у вас будет всего 4 столбца. Вставить очень похожую разметку в 3 раза не элегантно, но не так уж сильно. После того, как вы все заработаете, вы сможете решить, хотите ли вы выполнить рефакторинг и привести его в порядок.
Другой вариант - использовать два набора данных. Положите один под другим в стеке панели. Скройте заголовки на втором. Используйте это только для вставок.
Тогда у вас не будет новой строки редактирования в той же таблице данных, поэтому все ее столбцы могут быть обычными столбцами. В верхнем столбце есть столбцы, доступные только для чтения.
Если пользователь может изменить ширину столбца с помощью заголовков в верхней сетке данных, вам необходимо привязать ширину столбцов, чтобы они не выходили за пределы шага.
Третий вариант. Вставить, используя совершенно отдельную панель, а не сетку данных. Обычно я вообще не позволяю пользователям редактировать в сетке данных, так как это сложнее проверить, и у пользователей может возникнуть тенденция думать, что это просто отличный опыт, а не серьезные бизнес-данные. Я использую панель наложения вдоль линий этого. https://social.technet.microsoft.com/wiki/contents/articles/29777.wpf-property-list-editing.aspx Пользователь либо нажимает кнопку вставки, либо выбирает строку в сетке данных и нажимает кнопку редактирования.