2017-09-11 3 views
1

J'ai un DataGrid standard WPF 4 avec deux colonnes.WPF: DataGrid présentant une erreur de validation sur tous les DataGridTemplateColumns

<DataGrid ItemsSource="{Binding Source={StaticResource ItemDataView}}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTemplateColumn Header="Alpha"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Alpha}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
     <DataGridTemplateColumn Header="Beta"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Beta}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

Les objets de données affichés sont définis comme ceci:

public class MyObject : INotifyDataErrorInfo 
{ 
    [Required] 
    public string Alpha { get; set; } 

    public string Beta { get; set; } 

    public bool HasErrors 
    { 
     get { return string.IsNullOrEmpty(Alpha); } 
    } 

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; 

    public IEnumerable GetErrors(string propertyName) 
    { 
     yield return propertyName; 
    } 
} 

dire Alpha doit avoir une valeur non vide, mais Beta peut être nulle.

Si j'ajoute un objet MyObject où la valeur Alpha est vide, alors les deux les cellules Alpha et Beta reçoivent une bordure rouge indiquant une erreur de validation. Cela se produit uniquement pour DataGridTemplateColumns; J'ai essayé d'ajouter un DataGridTextColumn et il n'obtient pas la bordure rouge. La colonne Bêta obtient également une bordure rouge si elle n'est liée à rien, ou même si elle n'a pas de contrôle attaché (par exemple, DataTemplate est vide).

a) Pourquoi cela se produit-il?

b) Comment puis-je l'empêcher? Je veux seulement la bordure de validation rouge sur la cellule avec l'erreur.

+0

votre fonction HasErrors renvoie uniquement une évaluation de Alpha. Ainsi, la cellule bêta ne fera que refléter la condition de la cellule Alpha. –

Répondre

1

INotifyDataErrorInfo est utilisé pour déterminer s'il y a des erreurs. Plus précisément, la propriété HasErrors doit être implémentée pour renvoyer true ou false pour indiquer si des erreurs existent. Dans votre cas, la mise en œuvre est à la recherche ne HasErrors à Alpha:

public bool HasErrors 
{ 
    get { return string.IsNullOrEmpty(Alpha); } 
} 

Il ne montre qu'il ya des erreurs si Alpha est nul ou vide.

Vous devez modifier que pour vérifier les deux, comme ceci:

public bool HasErrors 
{ 
    get 
    { 
     return !AlphaIsValid || !BetaIsValid; 
    } 
} 

private bool AlphaIsValid 
{ 
    get {return !string.IsNullOrEmpty(Alpha);} 
} 

private bool BetaIsValid 
{ 
    get {return Beta == null || Beta != "";} 
} 

Puis, en GetErrors(), vérifiez la chaîne qui est passé pour voir si elle correspond à Alpha ou Beta, et fournir un message d'erreur pour chacun, comme ceci:

public IEnumerable GetErrors(string propertyName) 
{ 
    if (propertyName == nameof(Alpha) && !AlphaIsValid) 
    { 
     return new []{"Alpha is null or empty"}; 
    } 
    if (propertyName == nameof(Beta) && !BetaIsValid) 
    { 
     return new []{"Beta is empty"}; 
    } 
    return Enumerable.Empty<string>(); 
} 

Retourne une collection vide s'il n'y a pas d'erreur pour la propriété.

Actuellement, vous renvoyez une valeur pour les deux propriétés (en renvoyant simplement le nom de la propriété), les deux sont donc marquées comme ayant des erreurs de validation.

Pour référence: https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo(v=vs.110).aspx

+1

Modifiez les contrôles sur Bêta pour autoriser null et c'est une très bonne réponse. –

+0

@PaulGibson Merci. J'ai négligé cette partie. Réponse mise à jour –

+0

J'avais trop simplifié le problème, et après avoir lu votre lien de référence, je vois maintenant quel est le problème dans mon code actuel. J'utilisais une implémentation de GetErrors qui renvoyait TOUTES les erreurs de validation si le paramètre était nul. La référence indique que seules les erreurs au niveau de l'entité doivent être renvoyées dans ce cas. Il semble que GetErrors soit appelé avec un paramètre null pour tout DataGridTemplateColumn, qu'il ait ou non une liaison. – Deadlock320