Frage

Hat jemand die InotifyDataErrorinfo -Schnittstelle erfolgreich angewendet und an eine AutocompleteBox gebunden? Ich habe es versucht, aber ich bekomme keine Antwort. Die Kontrolle reagiert nicht, da andere kontrolliert dh mit einem roten Rand und einem Warntooltip. Außerdem wird die Validationsübersichtskontrollanzeige mit seinem Fehler nicht durchgeführt.

Ich habe erfolgreich Standard -Textboxen und DatePickers eingerichtet und verhalten sich perfekt wie die vielen Beispiele, die freundlicherweise von Personen im Internet bereitgestellt werden.

Es wäre gut, wenn es eine Antwort darauf auf die Konsistenz meines Bildschirms gäbe, auch weil ich einfach an die Eigenschaft Haserors binden möchte, die mit InotifyDataErrorinfo geliefert wird, um einen Knopf zu aktivieren, wenn es bereit ist, zu speichern, und ich kann dies ohne dies nicht tun Zusätzlicher Code, um zu überprüfen, ob diese Kästchen korrekt sind.

Im Moment behandle ich diese unterschiedlich, indem ich ein MVVMILL -EventTocommand -Bindung verwende und das LostFocus -Ereignis registriert.

<sdk:AutoCompleteBox x:Name="TransferTypeTextBox" SelectedItem="{Binding Path=SelectedTransferType, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" ItemsSource="{Binding Path=TransferTypes}" IsTextCompletionEnabled="True"  Grid.Row="1" Grid.Column="1" Margin="0,3" Width="238" HorizontalAlignment="Left" FontFamily="/PtrInput_Silverlight;component/Fonts/Fonts.zip#Calibri" FontSize="13.333">
      <i:Interaction.Triggers>
           <i:EventTrigger EventName="LostFocus">
               <cmd:EventToCommand Command="{Binding TransferTypeLostFocusCommand}" PassEventArgsToCommand="True"/>
           </i:EventTrigger>
      </i:Interaction.Triggers>
</sdk:AutoCompleteBox>

Im ViewModel habe ich dann die RouteDeVentargs.originalsource in ein Textfeld gegossen und den Text so abgerufen, sodass der Benutzer das Feld verlässt, es sei denn

    private void OnTransferTypeLostFocus(RoutedEventArgs e)
    {
        System.Windows.Controls.TextBox box = (System.Windows.Controls.TextBox)e.OriginalSource;

        // If user inputs text but doesn't select one item, show message.
        if (this.Ptr.TransferType == null && !string.IsNullOrEmpty(box.Text))
        {
            MessageBox.Show("That is not a valid entry for Transfer Type", "Transfer type", MessageBoxButton.OK);
            box.Focus();
        }
    }
War es hilfreich?

Lösung

Ich habe versucht, so einfach wie möglich zu schreiben. Mein Modell beobachtet Änderungen des Eigenschaftssuchtextes und Aktualisierung der Validierungseigenschaften.

public class MainViewModel : INotifyPropertyChanged, INotifyDataErrorInfo
{
    private Dictionary<string, List<string>> ErrorMessages = new Dictionary<string, List<string>>();

    public MainViewModel()
    {
        //Validation works automatically for all properties that notify about the changes
        this.PropertyChanged += new PropertyChangedEventHandler(ValidateChangedProperty); 
    }

    //Validate and call 'OnErrorChanged' for reflecting the changes in UI
    private void ValidateChangedProperty(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "HasErrors") //avoid recursion
            return;

        this.ValidateProperty(e.PropertyName);
        OnErrorsChanged(e.PropertyName);
        OnPropertyChanged("HasErrors");
    }

    //Just compare a received value with a correct value, it's a simple rule for demonstration
    public void ValidateProperty(string propertyName)
    {
        if (propertyName == "SearchText")
        {
            this.ErrorMessages.Remove(propertyName);
            if (SearchText != "Correct value")
                this.ErrorMessages.Add("SearchText", new List<string> { "Enter a correct value" });
        }

    }

    private string searchText;

    public string SearchText
    {
        get { return searchText; }
        set
        {
            searchText = value;
            OnPropertyChanged("SearchText");
        }
    }



    #region INotifyDataErrorInfo

    public IEnumerable GetErrors(string propertyName)
    {
        return this.ErrorMessages.Where(er => er.Key == propertyName).SelectMany(er => er.Value);
    }

    public bool HasErrors
    {
        get { return this.ErrorMessages.Count > 0; }
    }

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { };

    private void OnErrorsChanged(string propertyName)
    {
        ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
    }
    #endregion


    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Und xaml:

<sdk:AutoCompleteBox Text="{Binding SearchText, Mode=TwoWay}" />
<Button IsEnabled="{Binding HasErrors, Converter={StaticResource NotConverter}}" Content="Save"/>

Die Steuerung hat einen roten Rand und die Taste ist deaktiviert, wenn das Modell Fehler hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top