J'ai la méthode de validation suivante dans mon modèle de vue (l'exemple ne montre qu'une seule colonne, "ItemNumber") :
public bool IsValid
{
get
{
foreach (string property in ValidatedProperties)
if (GetValidationError(property) != null)
return false;
return true;
}
}
static readonly string[] ValidatedProperties =
{
"ItemNumber"
};
string GetValidationError(string propertyName)
{
if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
return null;
string error = null;
switch (propertyName)
{
case "ItemNumber":
error = this.ValidateItemNumber();
break;
default:
Debug.Fail("Unexpected property being validated on ProjectExpense: " + propertyName);
break;
}
// set the status message on the UI to the generated error
if (error != null)
{
ErrorMessage = error;
}
return error;
}
// string method
static bool IsStringMissing(string value)
{
return String.IsNullOrEmpty(value) || value.Trim() == String.Empty;
}
string ValidateItemNumber()
{
if (SelectedProjectExpenseItem != null)
{
if (IsStringMissing(SelectedProjectExpenseItem.ItemNumber))
{
return "Item number is required";
}
if (SelectedProjectExpenseItem.ItemNumber.Length > 50)
{
return "Item number exceeds 50 characters";
}
}
return null;
}
#endregion
#region IDataErrorInfo Members
string IDataErrorInfo.Error { get { return null; } }
string IDataErrorInfo.this[string propertyName]
{
get { return this.GetValidationError(propertyName); }
}
La validation se déclenche, mais je ne sais pas comment la communiquer à mon tableau de données. J'utilise un Dto séparé (d'où SelectedProjectExpenseItem.ItemNumber ci-dessus, SelectedProjectExpenseItem est mon Dto) au lieu d'avoir les propriétés directement dans mon viewmodel. Voici ma grille de données :
<DataGrid ItemsSource="{Binding Path=ListOfProjectExpenseItems}" AutoGenerateColumns="False"
Name="dgProjectExpenseItems" SelectionMode="Single" SelectionUnit="FullRow" CanUserResizeColumns="True"
SelectedItem="{Binding Path=SelectedProjectExpenseItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" GridLinesVisibility="Horizontal" CanUserDeleteRows="True" CanUserAddRows="True">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="SizeToCells" MinWidth="50" Binding="{Binding RowID}" />
<DataGridTextColumn Header="Project Expense ID" Width="SizeToCells" Visibility="Hidden" MinWidth="0" Binding="{Binding ProjectExpenseID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Item Number" Width="SizeToCells" MinWidth="140" Binding="{Binding ItemNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Item Description" Width="SizeToCells" MinWidth="250" Binding="{Binding ItemDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Unit Price" Width="SizeToCells" MinWidth="90" Binding="{Binding ItemUnitPrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Qty" Width="SizeToCells" MinWidth="65" Binding="{Binding ItemQty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Supplier Name" Width="SizeToCells" MinWidth="200" Binding="{Binding SupplierName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataGrid.Columns>
</DataGrid>
J'aimerais utiliser un style, par exemple avec une bordure rouge et une infobulle indiquant l'erreur, pour signaler un problème avec la ligne ou la cellule. Tous les exemples que j'ai trouvés utilisant des styles, cependant, ont les propriétés directement dans le viewmodel, et je n'arrive pas à comprendre comment le porter sur mon Dto.
Toute aide est appréciée.