Domanda

Quando si crea un IValueConverter personalizzato per un campo modificabile dall'utente, l'attuazione Convert è di solito abbastanza semplice.

L'attuazione ConvertBack non è, dato che (in assenza di una regola di convalida esplicito) deve affrontare ingresso utente negativa (es. Digitando "hi" in un campo di input numerico).

Se si verifica un errore durante la conversione, non sembra essere un modo per comunicare l'errore specifico:

  • ConvertBack non è autorizzato a lanciare eccezioni (se lo fa, il programma termina).
  • Restituzione di un ValidationError non fa nulla.
  • Tornando DependencyProperty.UnsetValue (che i documenti suggeriscono) si traduce in fallimento silenzioso (senza interfaccia utente errore viene mostrato all'utente, anche se hai impostato un modello di errore).
  • Tornando al valore non convertito originale dovesse causare errori interfaccia utente per essere mostrato, ma con testo di errore fuorviante.

Qualcuno sa di un modo migliore per gestire questo genere di cose?

. (Nota: durante la definizione di un ValidationRule personalizzato avrebbe funzionato, non credo che sia una buona risposta, dato che sarebbe fondamentalmente necessario duplicare la logica di conversione di scoprire l'errore in ogni caso)

È stato utile?

Soluzione

È possibile evitare la duplicazione di logica avendo il primo passo della regola di convalida è quello di chiamare il convertitore di valori per scoprire se il valore è la validazione è ancora utilizzabile.

Naturalmente, questo coppie vostre regole di validazione ai vostri convertitori di valore, a meno che non si effettua una regola di convalida che cerca l'associazione per scoprire cosa convertitore di valori è in uso. Ma se si inizia a scendere quella strada, prima poi sarà probabilmente accadere a voi, in quanto ha a molti, "aspetta, se sto usando MVVM, cosa sto facendo avvitamento intorno con i convertitori di valore?"

Modifica

Se il ViewModel implementa IDataErrorInfo, che in realtà è l'unico modo di vivere, è relativamente semplice per agganciare un convertitore di valori in un setter di proprietà senza scrivere un sacco di logica di convalida specifiche proprietà.

Nella classe ViewModel, creare due campi privati:

Dictionary<string, string> Errors;
Dictionary<string, IValueConverter>;

Crea loro (e popolare il secondo) nel costruttore. Inoltre, per IDataErrorInfo:

public string this[string columnName]
{
    return Errors.ContainsKey(columnName)
       ? Errors[columnName]
       : null;
}

Ora implementare un metodo come questo:

private bool ValidateProperty(string propertyName, Type targetType, object value)
{
   Errors[propertyName] = null;
   if (!Converters.ContainsKey(propertyName))
   {
      return true;
   }
   try
   {
      object result = Converters[propertyName].ConvertBack(value, targetType, null, null)
      return true;
   }
   catch (Exception e)
   {
      Errors[propertyName] = e.Message;
      return false;
   }
}

Ora il vostro setter di proprietà è simile al seguente:

public SomeType SomeProperty
{
   set
   {
      if (ValidateProperty("SomeProperty", typeof(SomeType), value))
      {
         _SomeProperty = value;
      }
   }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top