2011-09-05 11 views
5

ho i thats di controllo eredita dal testoValidationRules all'interno modello di controllo

public class MyTextBox : TextBox 

Questo ha uno stile

<Style TargetType="{x:Type Controls:MyTextBox}"> 

uno dei setter è

<Setter Property="Template"> 

voglio essere in grado di impostare lo Binding.ValidationRules su qualcosa nel modello, influenzando quindi tutte le istanze di questo tipo di testo bue. Posso quindi creare caselle di testo per dire orari, date, numeri, codici postali/postali ... o qualsiasi cosa desideri,

Non voglio dover impostare le regole di convalida ogni volta che creo una casella di testo. Voglio solo dire che voglio un NumericTextBox e farlo convalidare in qualsiasi modo sia impostato nel modello.

È possibile?

Tutto ciò che ho visto finora è il ValidationRules impostato su ciascuna istanza del controllo, ad es.

<TextBox x:Name="txtEMail" Template={StaticResource TextBoxErrorTemplate}> 
<TextBox.Text> 
    <Binding Path="EMail" UpdateSourceTrigger="PropertyChanged" > 
     <Binding.ValidationRules> 
      <local:RegexValidationRule Pattern="{StaticResource emailRegex}"/> 
     </Binding.ValidationRules> 
    </Binding> 
</TextBox.Text> 

(da http://www.wpftutorial.net/DataValidation.html)

risposta

1

Non sono sicuro che sia possibile fare esattamente ciò che si desidera. Potresti riuscire a farlo con un sacco di stratagemmi nei regolatori di proprietà (non farei affidamento su questo, poiché implicherebbe la modifica dei bind, che sono per definizione dinamici), o con codice dietro/controlli personalizzati.

Invece suggerisco di spingere la convalida nel ViewModel, probabilmente con IDataErrorInfo. Ci sono molti articoli là fuori. Ecco uno dei primi che ho trovato con una ricerca proprio ora "validazione MVVM":

MVVM - Validation

Fare questo vi permetterà di utilizzare le tecniche di composizione OO standard, in modo da poter avoid repeating yourself :)

+0

Penso che darò questo approccio –

4

Come si vede, le regole di convalida sono fissati insieme con le associazioni. Mi sono imbattuto lo stesso problema e la soluzione di lavoro per me è stato quello di fare qualcosa di simile:

public MyTextBox() 
    {    
     this.Loaded += new RoutedEventHandler(MyTextBox_Loaded); 
    } 

    void MyTextBox_Loaded(object sender, RoutedEventArgs e) 
    { 
     var binding = BindingOperations.GetBinding(this, TextBox.ValueProperty); 
     binding.ValidationRules.Add(new MyValidationRule()); 
    } 

Il problema qui è per essere sicuri che il legame è impostato prima di aggiungere la regola di convalida, da qui l'uso di Loaded , ma non sono sicuro se questo funzionerà su ogni scenario.

+0

Hmm . va bene. quindi come si adatta a mvvm. dovremmo mettere questa connessione vincolante e di convalida nel codice? Sarebbe altrettanto facile/difficile fare ogni legame sullo xaml e dimenticare il modello nel modo in cui l'avevo immaginato? –

+0

Questo approccio è indipendente dall'architettura e deve essere utilizzato per convalide generali, altrimenti non vedrò il punto di creare una nuova classe ereditata dalla casella di testo. Nel tuo esempio hai bisogno di verificare l'e-mail valida. Se hai bisogno di convalida dei dati specifici dell'app, dovresti sempre utilizzare IDataErrorInfo. – Natxo

+0

Sì, penso che con usercontrols sia corretto avere il codice nel codice. è un controllo utente, fa un lavoro specifico e può garantire che i suoi dati siano validi. –

Problemi correlati