1 votes

Validation à l'aide de IDataError

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.

0voto

blindmeis Points 10881

Avez-vous ValidatesOnDataErrors=True, ValidatesOnExceptions=True, NotifyOnValidationError=true active sur vos fixations ?

0voto

steveareeno Points 198

Les problèmes étaient liés à l'utilisation des Dto dans mon implémentation, ou du moins à l'absence d'implémentation de IDataErrorInfo dans ces Dto. J'ai décidé de m'en débarrasser et d'opter pour des objets métiers qui implémentent IDataErroInfo et voilà, tout fonctionne à merveille maintenant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X