I tried to solve this problem several times. In a DataGrid I display data about financial transactions. One column is the Account class which is a navigation property (EF). I have a simple validation. The Account property should be not empty.
Here is the column:
<DataGridTemplateColumn Header="{x:Static r:Resource.AccountName}"
CellTemplate="{StaticResource AccountTemplate}"
CellEditingTemplate="{StaticResource AccountEditingTemplate}" />
Here are the DataTemplates:
<DataTemplate x:Key="AccountEditingTemplate">
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}, Path=DataContext.AccountObjects}"
SelectedItem="{Binding Account, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"
DisplayMemberPath="Name" Style="{StaticResource ComboBoxError}" IsEditable="True"
ToolTip="{Binding Account.Name}" />
</DataTemplate>
<DataTemplate x:Key="NameTemplate">
<TextBlock Text="{Binding Name}" ToolTip="{Binding Name}"/>
</DataTemplate>
<DataTemplate x:Key="AccountTemplate">
<ContentControl Content="{Binding Path=Account, ValidatesOnDataErrors=True}"
ContentTemplate="{StaticResource NameTemplate}"/>
</DataTemplate>
The CellEditingTemplate displays the ComboBox with the potential accounts. The CellTemplate is tricky. In AccountTemplate I bound Account so I properly get the validation error. Then I use the NameTemplate to to display the Account.Name as a TextBlock. (Previously I bound "Account.Name" but validating a nested property is not easy if Account is null (e.g. in a new row)).
If I want to change Account in an existing row then everything works.
If I want to change Account in a new row then the ComboBox does not appear! (One more confusing fact, If I click to the Account in the new line then the ComboBox appear if then I go to another column I can not get back the ComboBox)
UPDATE 1
My problem is that with double click I can not open the editing mode. Here is the validation (but the problem still happens without the validation)
override public string this[string columnName]
{
get
{
var errorMessage = string.Empty;
switch (columnName)
{
case "Instrument":
if (Instrument == null)
errorMessage = nameof(Instrument) + " " + GlobalValues.AppData["must be given!"];
break;
case "Account":
if (Account == null)
errorMessage = nameof(Account) + " " + GlobalValues.AppData["must be given!"];
break;
}
return errorMessage;
}
}