2011-01-04 6 views
3

Ich versuche, WPF-Validierung für einige Textfelder zu implementieren. Ich möchte in der Lage sein, die Validierungsfehler dem Benutzer mit etwas offensichtlicherem als einem Tool-Tipp anzuzeigen, aber subtiler als ein Dialog oder eine Nachrichtenbox. Ich entschied mich eher für die Popup-Klasse als für ein eingebautes Textfeld zur Anzeige von Fehlern, da es viele verschiedene Felder gibt, die auf diese Weise validiert werden müssen, und ich möchte, dass das Feedback an das betreffende Feld "angehängt" wird.WPF-Validierungsergebnis-Popup

Das Problem, das ich erfahre, ist, dass die Bindung der untergeordneten TextBox des Popups an die Eigenschaft der angefügten TextBox (Validation.Errors) nicht genug aggressiv aktualisiert wird. Sobald ein Fehler-Objekt vorhanden ist, wird der Text aktualisiert und angezeigt (dh "Bitte geben Sie einen Namen ein." Für ein leeres Feld), aber wenn sich der Fehler ändert (dh der Benutzer gibt einen ungültigen Text ein), bleibt die Nachricht im Popup gleich ... bis/sofern sie keine gültige Eingabe eingeben, dann verschwindet das Popup wie gewünscht.

Ich habe einige Debugging durchgeführt, und ich habe festgestellt, dass, während die Validierungsregel korrekt aufgerufen wird und die richtigen Ergebnisse zurückgibt, der Konverter für das Popup nur bei der Erstellung des ursprünglichen Fehlers aufgerufen wird. Ich vermute, dass ich verwirrt bin, warum das Popup nur aktualisiert wird, wenn der Validierungsstatus sozusagen von "keine Fehler" zu "einigen Fehlern" wechselt. Kennt jemand eine Möglichkeit, die Änderungen zu Validation.Errors in meinem TextBox.Text Popup zu erzwingen?

Hier ist ein XAML-Beispiel von dem, was ich geschrieben habe.

<TextBox Name="MyTextBox"> 
    <TextBox.Text> 
     <Binding Path="MyText" UpdateSourceTrigger="PropertyChanged" > 
      <Binding.ValidationRules> 
       <local:MyTextBoxValidationRule /> 
      </Binding.ValidationRules> 
     </Binding> 
    </TextBox.Text> 
</TextBox> 
<Popup Name="MyPopup" IsOpen="{Binding ElementName=MyTextBox, 
    Path=(Validation.HasError), Mode=OneWay}"> 
    <Border BorderThickness="1" BorderBrush="Red" Background="White"> 
     <TextBlock Foreground="Red" Margin="5 5 5 5" 
      Text="{Binding ElementName=MyTextBox, Path=(Validation.Errors), 
      Converter={StaticResource errorsToMessageConverter}}"/> 
    </Border> 
</Popup> 

Antwort

1

Ich konnte einen Kompromiss finden. Ich änderte im Popup des TextBlock- die Bindung etwa so:

<TextBlock Name="MyPopupTextBox" Foreground="Red" Margin="5 5 5 5" 
    Text="{Binding ElementName=MyTextBox, Path=(Validation.Errors)[0].ErrorContent, 
    UpdateSourceTrigger=PropertyChanged, Mode=OneWay, NotifyOnValidationError=True, 
    NotifyOnSourceUpdated=True, ValidatesOnExceptions=True}"/> 
0

Ihr ursprüngliches Problem ist ein typisches Problem, wenn zu einer Sammlung Bindung: Solange Ihre Sammlung nicht strukturell nicht verändert (insert/Entfernen/Löschen), die Bindung wird keinen Grund zur Aktualisierung sehen. Wenn also nur ein Element in der Auflistung eine Eigenschaft ändert, führt dies nicht dazu, dass Ihre Bindung aktualisiert wird.

Sie haben dies bereits gelöst, indem Sie an das Element in dieser Sammlung gebunden haben. Auf diese Weise wird der vollständige Pfad zur geänderten Eigenschaft (der ErrorContent) in der Bindung beobachtet.

Das Problem mit (Validation.Errors)[0] Bindung ist, dass es IndexOutOfRange-Ausnahme wirft (nicht geworfen, aber sie sind dort), wenn die Fehler-Collection ist leer.

Dieser Thread diskutiert, dass die Ausnahme und enthält auch eine Abhilfe, die für mich funktioniert: http://social.msdn.microsoft.com/forums/en/wpf/thread/1c6cd214-abce-4a8b-a919-0726dd81461a/ Gerade (Validation.Errors)[0].ErrorContent von (Validation.Errors).CurrentItem.ErrorContent ersetzen und Sie sind fertig.