Microsoft-ui-xaml: Fügen Sie UWP mit INotifyDataErrorInfo Unterstützung für die Eingabevalidierung hinzu

Erstellt am 14. Jan. 2019  ·  50Kommentare  ·  Quelle: microsoft/microsoft-ui-xaml

Vorschlag: Eingabevalidierungsunterstützung mit INotifyDataErrorInfo hinzufügen

Zusammenfassung

Fügen Sie Eingabevalidierungsunterstützung mit INotifyDataErrorInfo hinzu, die von x:Bind und Binding unterstützt wird. Beide Markup-Erweiterungen sollten eine neue ValidatesOnNotifyDataErrors-Eigenschaft erhalten, die – wie in WPFs Binding – standardmäßig wahr ist.

Begründung

Derzeit hat UWP keine in die Plattform integrierte Eingabevalidierung. Aber jede Branchenanwendung erfordert eine Eingabevalidierung. Es ist eines der wichtigsten Features für eine richtige Unternehmens-App. Es gibt einen Eintrag auf uservoice, der besagt, dass diese Funktion mit WinUI kommen wird, aber ich habe noch nichts gesehen: https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/13052589-uwp-input -Validierung

feature proposal needs-winui-3 team-Markup

Hilfreichster Kommentar

INDEI erfordert, dass Sie alle Ihre Entitäten und Unterentitäten implementieren.

Können Sie das näher erläutern?

Durch die Verwendung von Regeln sind keine Änderungen erforderlich, alles funktioniert automatisch, indem nur Validierungsattribute verwendet werden.

Zum größten Teil funktioniert alles automatisch, wenn Sie auch ValidationAttributes und INotifyDataErrorInfo verwenden. Ich zeige hier einige Codeausschnitte, die in der Spezifikation enthalten sind, nur damit wir (hoffentlich) auf derselben Seite sind.

FWIW, wir planen, diese ValidationBase -Klasse live im Toolkit zu haben, sodass Sie diesen Boilerplate-Code nicht selbst schreiben müssen.

public class ValidationBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
   public event PropertyChangedEventHandler PropertyChanged;
   public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

   protected void SetValue<T>(ref T currentValue, T newValue, [CallerMemberName] string propertyName = "")
   {
       if (!EqualityComparer<T>.Default.Equals(currentValue, newValue))
       {
           currentValue = newValue;
           OnPropertyChanged(propertyName, newValue);
       }
   }

   readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
   public bool HasErrors
   {
       get
       {
           return _errors.Any();
       }
   }
   public IEnumerable GetErrors(string propertyName)
   {
       return _errors[propertyName];
   }

   private void OnPropertyChanged(string propertyName, object value)
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       Validate(propertyName, value);
   }

   private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
   {
       if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors = new List<ValidationResult>();
           _errors.Add(propertyName, errors);
       }

       errors.AddRange(results);
       ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
   }

   private void ClearErrors(string propertyName)
   {
       if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors.Clear();
           ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
       }
   }

   public void Validate(string memberName, object value)
   {
       ClearErrors(memberName);
       List<ValidationResult> results = new List<ValidationResult>();
       bool result = Validator.TryValidateProperty(
            value,
            new ValidationContext(this, null, null)
            {
                MemberName = memberName
            },
            results
            );

        if (!result)
        {
            AddErrors(memberName, results);
        }
    }
}

Ihr Modell würde dann von dieser Klasse abgeleitet und wie folgt aussehen:

public class Person : ValidationBase
{
    private string name;
    [MinLength(4)]
    [MaxLength(6)]
    public string Name
    {   
        get { return name; }
        set { SetValue(ref name, value); }
    }
}

Angenommen, diese Person Klasse ist auf eine ViewModel Eigenschaft auf Ihrem Page gesetzt, dann binden Sie sich daran und die Validierung erfolgt automatisch:

<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />

Ich verstehe, dass dies möglicherweise ein wenig anders ist als das, was Sie heute tun, aber wir versuchen, nicht zwei verschiedene Methoden zu unterstützen, um dasselbe zu tun, wenn dies nicht erforderlich ist. Lassen Sie mich wissen, ob dies sinnvoll ist oder wenn Sie der Meinung sind, dass uns noch etwas fehlt!

Alle 50 Kommentare

@LucasHaines, wie hängt das mit den Eingabevalidierungsfunktionen zusammen, die Sie untersucht haben?

@jevansaks Dies steht in direktem Zusammenhang mit der Eingabevalidierungsarbeit, die ich skizziere.

Toll. Wenn Sie Vorschaumaterial zum Teilen haben, probiere ich es gerne aus und gebe Feedback und Gedanken.

image

Dies ist die Art der Validierung, die während Build 2018 erwähnt wurde

`
x:Name="Benutzername" Header="Benutzername:"
Text="{x:Bind ViewModel.Person.Benutzername,
UpdateSourceTrigger=Eigenschaft geändert,
Modus=ZweiWeg}" />

x:Name="Passwort" Header="Passwort:"
Password="{x:Bind ViewModel.Person.Password,
UpdateSourceTrigger=LostFocus,
Modus=ZweiWeg}"/>
`

@thomasclaudiushuber wie wichtig ist es deiner Meinung nach, diese Arbeit als Teil von {Binding} zu machen? Ich frage nur, weil die technischen Herausforderungen dort nicht trivial sind und es nicht möglich ist, Downlevel zu arbeiten. Unsere ursprüngliche Idee war, nur x:Bind zu unterstützen, was nur Markup-Compiler-Änderungen erfordert und in der Lage ist, auf einer niedrigeren Ebene zu arbeiten.

Außerdem planten wir nur die Unterstützung des INotifyDataErrorInfo- und DataAnnotations-Paradigmas. Wir hatten nicht die Absicht, etwas Analoges zu Binding.ValidationRules hinzuzufügen, und waren daher nicht der Meinung, dass ein ausreichender Bedarf an ValidatesOnNotifyDataErrors besteht.

Wir würden gerne Ihr Feedback erhalten, während wir weiter an dieser Funktion arbeiten, damit es richtig gemacht werden kann!

@stevenbrix

Kurze Antwort: Ja, was Sie denken und was Sie vorhaben, klingt großartig. Nur x:Bind ist in Ordnung, und nur INotifyDataErrorInfo ist auch in Ordnung.

Lang:

Nur x:binden? 👍

In allen WPF-LOB-Fällen, die mir einfallen, gab es immer eine Art ViewModel, das zur Kompilierzeit bekannt war, keine Enteneingabe, also ist x:Bind in Ordnung. Ich habe in dieser Ausgabe auch {Binding} geschrieben, da ich dachte, dass Sie es unterstützen können, um die gleiche Syntax wie in WPF zu erhalten. Aber das ist eher "nice to have" als super wichtig. Und da {Binding} und x:Bind hinter den Kulissen zwei völlig unterschiedliche Dinge sind und das Laufzeit-Zeug mit {Binding} nicht trivial ist, wie Sie erwähnt haben, vergessen Sie {Binding}. Ich denke, es nur für x:Bind zu haben, ist völlig in Ordnung, es wird für die Anwendungsfälle funktionieren, die mir einfallen. Und aus all den Konferenzgesprächen, die ich zu UWP und x:Bind geführt habe, kann ich Ihnen sagen, dass x:Bind eines der beliebtesten UWP-Features aller XAML-Entwickler ist, und ich habe allen gesagt: „Bevorzugen Sie x:Bind gegenüber Binding, wo immer Sie sind kann". :) Das Abrufen von Intellisense-, Perf-, Step-In-Code- und Kompilierzeitfehlern macht x:Bind zum neuen Standard für UWP, also ist es in Ordnung und imo eine gute Entscheidung, die Validierungsunterstützung nur dort zu haben.

Nur INotifyDataErrorInfo und DataAnnotations-Paradigma? 👍

Nur das INotifyDataErrorInfo- und DataAnnotations-Paradigma zu unterstützen, klingt für mich gut. WPF nimmt Datenanmerkungen nicht automatisch auf, Sie müssen sie manuell in Ihrer INotifyDataErrorInfo-Implementierung mithilfe der Validator-Klasse verknüpfen. Sie meinen das, wenn Sie "DataAnnotations-Paradigma" sagen, richtig? Oder planen Sie eine integrierte DataAnnotation-Unterstützung, die es einem Entwickler ermöglicht, einfach eine Data Annotation auf eine Eigenschaft zu setzen, und das funktioniert einfach? Wie in ASP.NET Core MVC? Das wäre zwar toll, aber ich denke, es ist nicht notwendig. Imo reicht es aus, die Klassen ValidationContext, Validator und ValidationResult und die anderen Klassen aus System.ComponentModel.DataAnnotations zu haben.

Binding.ValidationRules hinzufügen? Nööööö ;-)

Nein, füge das definitiv nicht hinzu. INotifyDataErrorInfo ist genug und es ist das Beste. Ich glaube, ich habe ValidationRules nie mehr verwendet, nachdem die IDataErrorInfo-Unterstützung zu WPF hinzugefügt wurde (wenn ich mich richtig erinnere, war dies in .NET Framework 3.5). Und als INotifyDataErrorInfo in .NET Framework 4.5 hinzugefügt wurde, haben meine Kunden und ich diese Schnittstelle in allen Projekten zur Eingabevalidierung verwendet. Es ist in Ordnung, nur diese Schnittstelle zu unterstützen.

ValidatesOnNotifyDataErrors hinzufügen? Nein, aber...

Ja, Sie müssen diesen nicht hinzufügen. Aber es hat nichts mit den Binding.ValidationRules zu tun. Diese Eigenschaft steht in direktem Zusammenhang mit der INotifyDataErrorInfo-Schnittstelle. In der Binding Markup Extension von WPF ist ValidatesOnNotifyDataErrors standardmäßig wahr, was bedeutet, dass {Binding} die implementierte INotifyDataErrorInfo-Validierung aufnimmt, wenn das gebundene Objekt diese Schnittstelle implementiert. Wenn Sie die ValidatesOnNotifyDataErrors-Eigenschaft der Binding-Markuperweiterung auf „false“ festlegen, übernimmt die Binding-Markuperweiterung die INotifyDataErrorInfo-Implementierung nicht für die Validierung. Vielleicht ist das mit x:Bind nicht allzu schwer zu implementieren, aber vielleicht brauchen wir es nicht. Also, nein, tu es nicht. Es ist in Ordnung, dies wegzulassen. Aber lassen Sie mich das Szenario beschreiben, in dem ich dies in der Vergangenheit benötigte:

WPF-Steuerelemente zeigen standardmäßig einen roten Rahmen, der über das Validation.ErrorTemplate definiert wird. Nehmen wir nun an, Sie haben eine INotifyDataErrorInfo-Implementierung mit einer Klasse, die über die FirstName-Eigenschaft verfügt. Es ist erforderlich, sodass Sie einen Fehler zurückgeben, wenn die FirstName-Eigenschaft null oder leer ist. Jetzt haben Sie eine TextBox an diese FirstName-Eigenschaft gebunden. Wenn ein Benutzer diesen Vornamen entfernt, wird ein roter Rahmen angezeigt. Super, genau das was du willst. Aber vielleicht haben Sie an anderer Stelle in der Benutzeroberfläche ein anderes Steuerelement, das ebenfalls an die FirstName-Eigenschaft gebunden ist. Zum Beispiel ein TextBlock in einem Tab-Header. WPF zeigt auf diesem TextBlock auch einen roten Rahmen an, wenn ein Validierungsfehler vorliegt. Aber das ist vielleicht nicht das, was Sie wollen. Sie möchten den Fehler nur in der TextBox, in der der Benutzer den Vornamen ändern kann, aber nicht im TextBlock im Tab-Header. Um den roten Rand des TextBlocks zu entfernen, müssen Sie das ErrorTemplate des TextBlocks nicht bearbeiten, sondern deaktivieren einfach die INotifyDataErrorInfo-Validierung für die TextBlock-FirstName-Binding, indem Sie die ValidatesOnNotifyDataErrors-Eigenschaft auf „false“ setzen. Das ist der einzige Anwendungsfall, den ich jemals für diese Eigenschaft hatte. :)

Ich hoffe das hilft.

Zusammenfassung

Ja, ich stimme voll und ganz zu, eine Eingabevalidierung nur auf x:Bind mit Unterstützung für INotifyDataErrorInfo ist ein guter Plan.

Nein, es ist ein fantastischer Plan, ich bin schon super aufgeregt!

@thomasclaudiushuber danke für die ausführliche Nachbereitung! Die Kernszenarien, die Sie beschreiben, stimmen mit dem überein, was wir für den wahren Werttreiber hielten, und das ist gut zu hören. Das Gesamtdesign dieser Funktion und API war im Fluss, hauptsächlich aufgrund der früheren Arbeit von WPF. Hier gab es ein paar wichtige Dinge zu nennen:

  1. Wie oben besprochen, gab es bestimmte Aspekte des WPF-Validierungssystems, die wir nicht als Mehrwert empfanden oder die durch bessere Muster ersetzt wurden, und daher hatten wir nicht vor, sie in UWP zu integrieren.

  2. Bestimmte Features/Funktionen des Validierungssystems von WPF nutzen die Vorteile von WPF-Kernfunktionen, die in UWP nicht vorhanden sind. Am bemerkenswertesten ist hier die Adorner-Schicht, die es jedem UIElement in WPF ermöglicht, Validierungsvisuals anzuzeigen, nicht nur Steuerelemente (durch Hinzufügen eines Vorlagenteils).

  3. UWP-XAML verfügt derzeit nicht über das Konzept angefügter Ereignisse, und das Spiegeln der Klasse „Validation“ würde das Ereignis „Validation.Error“ hinzufügen. Nicht das ist ein Deal Breaker, nur etwas, das wir erwähnen sollten, da wir im Allgemeinen vorsichtig sind, neue Konzepte hinzuzufügen, da dies nur die Komplexität erhöht. Da die Arbeit außerdem Änderungen an der Vorlage des Steuerelements erfordert, funktionieren nur die Steuerelemente, für die wir die spezifischen Vorlagenänderungen bereitstellen, sofort. Im Allgemeinen ist es keine gute Praxis, eine API zu haben, die zu funktionieren scheint, aber in einigen Szenarien nicht funktioniert, und deshalb dachten wir, es wäre besser, uns von diesem Modell zu trennen. Dies würde bedeuten, etwas anderes wie eine gemeinsame Schnittstelle und/oder Attribute zu haben, die die Implementierung steuern.

Wir sind immer noch dabei zu verstehen, wie API- und Spezifikationsüberprüfungen in der neuen und aufregenden Open-Source-Welt durchgeführt werden. Wir würden gerne das Feedback der Community erhalten, also können wir die API-Vorschläge hoffentlich bald veröffentlichen, damit die Community einen Blick darauf werfen und uns helfen kann, etwas zu landen, worüber sich alle freuen!

@stevenbrix Wenn Sie mit der Open-Source-Spezifikation für die Validierungsfunktionen beginnen, stellen Sie die Illustrationen bereit, wie die Validierung aussehen wird, sowie die Beispielszenarien, damit die Konversation für diejenigen von uns, die sich mehr mit der UI-Seite befassen, etwas breiter sein kann , als die Codierung :)

@mdtauk Absolut. Die aktuelle Benutzeroberfläche, die wir geteilt haben, ist immer noch korrekt. Wenn Sie Feedback haben, können Sie dies gerne in diesem Thread tun.

@LucasHaines Die Benutzeroberfläche sieht für mich gut aus. Aber ich frage mich, wie Sie einstellen können, wie die Fehler angezeigt werden. Ich habe diesbezüglich nichts gefunden und ich weiß nicht, ob Sie in diesem Bereich bereits etwas mitzuteilen haben. Wird es etwas Ähnliches wie die angehängte Validation.ErrorTemplate-Eigenschaft von WPF geben?

Gibt es einen Zeitplan dafür, wann eine formelle Spezifikation/ein Vorschlag dafür veröffentlicht wird?
Was kann ich tun, damit dies früher in das Produkt gelangt?

Ich stimme @mrlacey oben zu ... Ich könnte das jetzt wirklich gebrauchen, also helfe ich gerne, wo ich kann.

Wir arbeiten an einer offenen Spezifikation und ich werde alle wissen lassen, dass sie im Spezifikationsrepo verfügbar ist.

Frage: Warum nicht auch IDataErrorInfo unterstützen? Es wird im .net-Standard unterstützt, und es wäre seltsam, es nicht zu unterstützen? Dies sollte die Leistung für die Personen, die es nicht verwenden, nicht beeinträchtigen, da sogar zur Kompilierzeit überprüft werden könnte, welche Schnittstelle für die Bindung verwendet werden soll?

Wir haben die offene Spezifikationsüberprüfung für die Eingabevalidierung im offenen Spezifikationsrepo gestartet. https://github.com/Microsoft/microsoft-ui-xaml-specs/pull/26

Hallo Leute, wie verfolgen wir das - haben wir eine ETA?

@knightmeister Wir haben hier eine offene Spezifikation erstellt. Bitte zögern Sie nicht, an der Überprüfung teilzunehmen und das Feature mitzugestalten. Wir planen, dies als Teil von WinUI 3.0 auszuliefern. Weitere Informationen zur WinUI 3.0-Roadmap finden Sie in Ausgabe Nr. 717.

Hallo zusammen - bitte werfen Sie einen Blick auf die neuesten Beispiele in der Spezifikation. @stevenbrix hat einige großartige Aktualisierungen an den Beispielen vorgenommen und auf andere Rückmeldungen eingegangen.

Eine Frage: Werden die Validierungsinformationen in die Kontrollhierarchie einfließen? Wird es beispielsweise möglich sein, dass ein Container-Steuerelement (z. B. TabView oder Pivot) erkennt, dass sich ein untergeordnetes Steuerelement in einem ungültigen Zustand befindet?

Stellen Sie sich eine komplexe Ansicht mit mehreren Containersteuerelementen vor, in der Sie hervorheben möchten, welche Teile der Ansicht Ihrer Aufmerksamkeit bedürfen, indem Sie beispielsweise den Stil eines Pivot-Headers ändern, wenn sich ein untergeordnetes Steuerelement in einem ungültigen Zustand befindet.

Dies ist ein kritisches Thema für mich.
Mein gesamtes XAML-Validierungssystem basiert auf WPF-Validierungsregeln, es liest das Feld- und Entitätsmodell aus dem BindingExpression und erstellt Validierungsregeln gemäß den DA-Validierungsattributen (siehe this ).

Wird es beispielsweise möglich sein, dass ein Container-Steuerelement (z. B. TabView oder Pivot) erkennt, dass sich ein untergeordnetes Steuerelement in einem ungültigen Zustand befindet?

@tbolon ja, das ist etwas, das getan werden kann, obwohl es unwahrscheinlich ist, dass in diesen Containern Unterstützung dafür eingebaut wird. Wir haben darüber nachgedacht, ein Form -Steuerelement zu erstellen, das diese Funktionalität integriert hätte, aber es befindet sich derzeit wahrscheinlich im Rückstand. Wie in WPF gibt es ein ValidationError -Ereignis (dieser Name könnte falsch sein), das jedes Steuerelement auslöst, wenn es ungültig/gültig wird. Dieses Ereignis ist jedoch kein Routing-Ereignis, daher müssen Sie jedes Element abonnieren, das Sie hören möchten.

Mein gesamtes XAML-Validierungssystem basiert auf WPF-Validierungsregeln,

@weitzhandler Wir planen derzeit nicht, WinUI so etwas wie ValidationRule hinzuzufügen. Gibt es etwas, das Ihnen die Verwendung ValidationAttributes und die Implementierung INotifyDataErrorInfo in Ihrem Modell überflüssig macht? Ich würde gerne sehen, wie Ihr Modell und XAML aussehen, um Ihr Nutzungsszenario besser zu verstehen.

INDEI erfordert, dass Sie alle Ihre Entitäten und Unterentitäten implementieren.
Durch die Verwendung von Regeln sind keine Änderungen erforderlich, alles funktioniert automatisch, indem nur Validierungsattribute verwendet werden.

INDEI erfordert, dass Sie alle Ihre Entitäten und Unterentitäten implementieren.

Können Sie das näher erläutern?

Durch die Verwendung von Regeln sind keine Änderungen erforderlich, alles funktioniert automatisch, indem nur Validierungsattribute verwendet werden.

Zum größten Teil funktioniert alles automatisch, wenn Sie auch ValidationAttributes und INotifyDataErrorInfo verwenden. Ich zeige hier einige Codeausschnitte, die in der Spezifikation enthalten sind, nur damit wir (hoffentlich) auf derselben Seite sind.

FWIW, wir planen, diese ValidationBase -Klasse live im Toolkit zu haben, sodass Sie diesen Boilerplate-Code nicht selbst schreiben müssen.

public class ValidationBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
   public event PropertyChangedEventHandler PropertyChanged;
   public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

   protected void SetValue<T>(ref T currentValue, T newValue, [CallerMemberName] string propertyName = "")
   {
       if (!EqualityComparer<T>.Default.Equals(currentValue, newValue))
       {
           currentValue = newValue;
           OnPropertyChanged(propertyName, newValue);
       }
   }

   readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
   public bool HasErrors
   {
       get
       {
           return _errors.Any();
       }
   }
   public IEnumerable GetErrors(string propertyName)
   {
       return _errors[propertyName];
   }

   private void OnPropertyChanged(string propertyName, object value)
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       Validate(propertyName, value);
   }

   private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
   {
       if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors = new List<ValidationResult>();
           _errors.Add(propertyName, errors);
       }

       errors.AddRange(results);
       ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
   }

   private void ClearErrors(string propertyName)
   {
       if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors.Clear();
           ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
       }
   }

   public void Validate(string memberName, object value)
   {
       ClearErrors(memberName);
       List<ValidationResult> results = new List<ValidationResult>();
       bool result = Validator.TryValidateProperty(
            value,
            new ValidationContext(this, null, null)
            {
                MemberName = memberName
            },
            results
            );

        if (!result)
        {
            AddErrors(memberName, results);
        }
    }
}

Ihr Modell würde dann von dieser Klasse abgeleitet und wie folgt aussehen:

public class Person : ValidationBase
{
    private string name;
    [MinLength(4)]
    [MaxLength(6)]
    public string Name
    {   
        get { return name; }
        set { SetValue(ref name, value); }
    }
}

Angenommen, diese Person Klasse ist auf eine ViewModel Eigenschaft auf Ihrem Page gesetzt, dann binden Sie sich daran und die Validierung erfolgt automatisch:

<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />

Ich verstehe, dass dies möglicherweise ein wenig anders ist als das, was Sie heute tun, aber wir versuchen, nicht zwei verschiedene Methoden zu unterstützen, um dasselbe zu tun, wenn dies nicht erforderlich ist. Lassen Sie mich wissen, ob dies sinnvoll ist oder wenn Sie der Meinung sind, dass uns noch etwas fehlt!

Sie haben Recht, aber das erfordert, dass Ihre Entitäten keine POCOs sind.
Ich sollte es mal versuchen. Könnte nicht so schlimm sein, eine EntityBase -Klasse in einer LoB-App zu verwenden. Ich bin nur daran gewöhnt, POCOs zu verwenden.

UWP hat keine * Validierung* !!!!!! Ich habe gerade ein Projekt gestartet. Zurück zu WPF bis vor ein paar Jahren.

@rufw91 Ich weiß, oder?!

Was sind Ihre zeitlichen Einschränkungen? Die erste Implementierung davon ist in WinUI3 Alpha, und wir sollten bald eine Vorschau für den WinUI-Desktop im //Build-Zeitrahmen haben. Wir planen RTM'ing bis Ende des Jahres

UWP hat keine * Validierung* !!!!!! Ich habe gerade ein Projekt gestartet. Zurück zu WPF bis vor ein paar Jahren.

Ich habe mich entschieden, auch in den kommenden Jahren bei WPF zu bleiben. Ich habe alles gemacht (WPF, SL, WP, UWP usw.), am Ende scheint nur eine Technologie solide zu sein, nämlich WPF. Vielleicht könnte es in ein paar Jahren interessant sein, herauszufinden, wo WinUI ist, aber ich bin es leid, auf neue Technologien umzusteigen und allein im Dunkeln gelassen zu werden. WPF ist ausgereift und funktioniert hervorragend. Vielleicht ist Windows als Betriebssystem in ein paar Jahren überhaupt nicht mehr relevant, also warten wir das ab, bevor wir weitere Investitionen in die Plattform tätigen.

Vielleicht ist Windows als Betriebssystem in ein paar Jahren überhaupt nicht mehr relevant, also warten wir das ab, bevor wir weitere Investitionen in die Plattform tätigen.

Wenn man bedenkt, dass wir gerade die Marke von 1 Milliarde Windows 10-Installationen überschritten haben, fällt es mir schwer zu glauben, dass das jemals wahr sein wird. Aber ich spüre definitiv Ihre Frustration und mache Ihnen keine Vorwürfe, dass Sie bei WPF bleiben. FWIW, unser Team übernimmt jetzt WPF, also lassen Sie es mich wissen, wenn Sie uns dort etwas sehen möchten.

INDEI erfordert, dass Sie alle Ihre Entitäten und Unterentitäten implementieren.

Können Sie das näher erläutern?

Mit meinem Code können alle POCO-Entitäten frei von der Implementierung dieser Schnittstellen und ohne Basisklasse bleiben. INPC wird mit Fody automatisch implementiert. Ich würde höchstens IValidatableObject implementieren, wenn eine verfeinerte Validierung erforderlich ist. Und es funktioniert auch bei Untertypen.

FWIW, wir planen, diese ValidationBase -Klasse live im Toolkit zu haben, sodass Sie diesen Boilerplate-Code nicht selbst schreiben müssen.

Das ist nicht gut. Was ist, wenn meine Entitäten bereits eine Basisklasse haben? Deshalb bin ich auch kein so großer Fan von INotifyDataErrorInfo . INPC-Eigenschaften bereiten bereits Kopfschmerzen, insbesondere wenn es um riesige Daten-Apps mit Tonnen von Entitäten geht.

Es ist ziemlich schockierend, dass UWP noch keine ordnungsgemäße Validierung hat. Das ist ein entscheidendes Grundfeature in fast jeder App und sollte an erster Stelle stehen.

Es ist ziemlich schockierend, dass UWP noch keine ordnungsgemäße Validierung hat. Das ist ein entscheidendes Grundfeature in fast jeder App und sollte an erster Stelle stehen.

Ja, deswegen arbeiten wir daran :)

Das ist nicht gut. Was ist, wenn meine Entitäten bereits eine Basisklasse haben?

Ich versuche nur, Ihre Verwendung hier zu verstehen. Was ist die Basisklasse und könnte sie von dieser Klasse abgeleitet werden?

Ja, deswegen arbeiten wir daran :)

Vielen Dank, sehr geschätzt. Dies und der Rest Ihrer Arbeit.
Was bedeutet die Bezeichnung „ needs-winui-3 “?

Ich versuche nur, Ihre Verwendung hier zu verstehen. Was ist die Basisklasse und könnte sie von dieser Klasse abgeleitet werden?

Ich verwende OData Connected Service , um auf meinem Client generierte Entitäten zu erhalten.
Die generierten Objekte haben dieses Muster:

c# public abstract partial class ContactBase : Microsoft.OData.Client.BaseEntityType, INotifyPropertyChanged

Was bedeutet die Bezeichnung „needs-winui-3“?

@weitzhandler
Dies impliziert, dass die Eingabevalidierung mit WinUI 3. (3.0 wie derzeit geplant) geliefert wird. Es wird wahrscheinlich nicht zu WinUI 2 kommen, da dies Änderungen am XAML-Code des Betriebssystems erfordern würde, der sich derzeit im Wartungsmodus befindet.

Ich verwende UWP in einer Uno-Plattform-App. Hoffentlich wird WinUI nach seiner Veröffentlichung behandelt.
Danke für das Update!

Ich versuche nur, Ihre Verwendung hier zu verstehen. Was ist die Basisklasse und könnte sie von dieser Klasse abgeleitet werden?

Das Vorhandensein einer Basisklasse wird häufig von Drittanbietern vorgeschrieben, z. B. dem von Ihnen verwendeten Persistenz-Framework. UWP/WinUI, das auch eine Basisklasse nur zur Validierung fordert, ist keine Option. Es muss eine Schnittstelle sein, um nützlich zu sein, keine unserer Anwendungen könnte eine Basisklasse verwenden. (Das bedeutet nicht, dass Sie keine Basisklasse für Personen haben können, die sie verwenden möchten, sie muss nur optional und nicht die einzige Möglichkeit zur Validierung sein.)

Das Vorhandensein einer Basisklasse wird häufig von Drittanbietern vorgeschrieben, z. B. dem von Ihnen verwendeten Persistenz-Framework. UWP/WinUI, das auch eine Basisklasse nur zur Validierung fordert, ist keine Option. Es muss eine Schnittstelle sein, um nützlich zu sein, keine unserer Anwendungen könnte eine Basisklasse verwenden.

Gehen wir etwas zurück. Ich denke, die letzten paar Kommentare, die ich gemacht habe, haben ein wenig Verwirrung gestiftet, was ich schlecht finde.

Das Modell muss lediglich System.ComponentModel.INotifyDataErrorInfo (oder Windows.UI.Xaml.Data.INotifyDataErrorInfo für C++) implementieren. Der Compiler generiert den Code ordnungsgemäß, um das mit Ihrer Ansicht zu verbinden, wenn Sie {x:Bind} verwenden.

Die Klasse ValidationBase , auf die ich mich oben bezogen habe, ist eine Hilfsklasse, die wir zusammen mit INotifyPropertyChanged im Community-Toolkit bereitstellen wollten, das dies implementiert. Es besteht keine Notwendigkeit, davon abzuleiten, wenn Ihr Anwendungsfall dies nicht zulässt.

Danke für deine Klarstellung @stevenbrix.

Was ist mit Validierungsattributen und IValidatableObject , werden sie von der UWP-Laufzeit respektiert?

Wie wäre es mit anderen Attributen, wie dem zuvor erwähnten MaxLength -Attribut, wird eine maximale Länge TextBox automatisch wie in ASP.NET festgelegt?
Dasselbe gilt für DataTypeAttribute , EditableAttribute .
Auch DisplayAttribute zum Generieren von Feldüberschriften.
Soweit ich mich erinnere, wurden sie alle in Silverlight unterstützt.

(siehe dazu ).

Was ist mit Validierungsattributen und IValidatableObject, werden sie von der UWP-Laufzeit respektiert?

Wir werden also derzeit Unterstützung für das Attribut Required haben. Einige Steuerelemente setzen automatisch ein kleines Sternchen neben den Kopfzeilentext, wenn dies verwendet wird. Wir sind offen dafür, in Zukunft mehr zu unterstützen, wenn Sie möchten. Bitte öffnen Sie eine separate Ausgabe, wenn Sie mehr sehen möchten, und nur um die Erwartungen zu wecken, es ist sehr unwahrscheinlich, dass zusätzliche Attributunterstützung die erste WinUI3-Version enthält.

Was IValidatableObject , bin ich mir nicht sicher, wie das funktionieren würde. Als Verallgemeinerung funktioniert unsere Engine einfach, indem sie auf das Ereignis INotifyDataErrorInfo.ErrorsChanged lauscht. Die eigentliche Validierung des Modells obliegt dem App-Entwickler und erfolgt im Allgemeinen beim Übertragen des Werts vom Ziel auf die Quelle.

Vielleicht sollte es als alternative Methode zu dem von Ihnen vorgeschlagenen ValidationBase eine Reihe von Erweiterungsmethoden geben, die einen Validierungsprozess mit Validator.TryValidateObject ausführen und die Validierungsergebnisse in die Entität einfügen und die Änderungen melden ?
Auf diese Weise kann es einfach erreicht werden, indem einfach INotifyDataErrorInfo implementiert wird. Wir könnten auch eine Schnittstelle haben, die von INotifyDataErrorInfo erbt, die eine Eigenschaft hinzufügt, die die Fehlersammlung enthält, sodass die UWP-Laufzeit oder das Toolkit stattdessen als automatisiert validierbare Entität erkennen und die Eigenschaft automatisch festlegen kann, wenn sie implementiert ist.

Vielleicht sollte es als alternative Methode zu der von Ihnen vorgeschlagenen ValidationBase eine Reihe von Erweiterungsmethoden geben, die einen Validierungsprozess mit Validator.TryValidateObject ausführen und die Validierungsergebnisse in die Entität einfügen und die Änderungen mitteilen?

Das ist eine tolle Idee :)

🦙 Sie fragen sich, ob die neuen Quellengenerator-Paradigmen auch hier helfen könnten?

Ja @michael-hawker, ich mag deine Gedanken!

Ich hatte vor einiger Zeit die gleichen Gedanken, als ich zum ersten Mal von den neuen Möglichkeiten des Quellengenerators las.

Ich denke, mit den neuen Source-Generator-Paradigmen können wir eine Menge Dinge hinter den Kulissen für INotifyDataErrorInfo und INotifyPropertyChanged erstellen / generieren.

Ich habe einen WPF-Kurs zu Pluralsight, der genau das mit T4, INotifyPropertyChanged und INotifyDataErrorInfo macht, einschließlich Datenanmerkungen zur Validierung: https://www.pluralsight.com/courses/wpf-mvvm-advanced-model-treatment
Der Kurs verwendet auch benutzerdefinierte angehängte Eigenschaften, um Dinge miteinander zu verbinden.
Das Ziel dieses Kurses ist es zu zeigen, wie Sie eine MVVM WPF-App erstellen können, die in jedem Eingabefeld anzeigt, ob es geändert wurde und was der ursprüngliche Wert war.

Also, auf jeden Fall wäre es großartig, Dinge zu generieren und vielleicht mit einer Bibliothek zu enden (vielleicht als Teil von WCT). Und ich würde diesen Kurs gerne für WinUI wiederholen. :)

@rufw91 Ich weiß, oder?!

Was sind Ihre zeitlichen Einschränkungen? Die erste Implementierung davon ist in WinUI3 Alpha, und wir sollten bald eine Vorschau für den WinUI-Desktop im //Build-Zeitrahmen haben. Wir planen RTM'ing bis Ende des Jahres

@stevenbrix Ich hoffe es, ich musste zurück zu WPF wechseln, eigentlich bin ich jetzt fast fertig.

Ich habe diese geöffnet.

Um dem nachzugehen, habe ich nach einem Gespräch mit @stevenbrix auf Twitter die grundlegende INotifyDataErrorInfo -Implementierung, die er hier bereitgestellt hat, in eine neue ObservableValidator -Klasse integriert, die im neuen MVVM-Toolkit (the Microsoft.Toolkit.Mvvm Bibliothek), die auch INotifyPropertyChanged und INotifyPropertyChanging 😄 implementiert

Sie können den zugehörigen Code und eine Zusammenfassung von allem, was mit dieser Bibliothek zusammenhängt, in dieser Ausgabe sehen.
Ich habe dort auch Links zur Originalausgabe des MVVM-Toolkits sowie weitere Dokumente für neue Entwickler hinzugefügt.

Können Sie uns diesbezüglich bitte ein Update geben? Neugierig, ob UWP 10.0 18362 INotifyDataErrorInfo unterstützt. Laut der folgenden Dokumentationsseite gilt https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=netcore-3.1 INotifyDataErrorInfo für UWP 10.0. Wenn UWP 10.0 18362 jedoch installiert und als Ziel verwendet wird, zeigen die Textfelder keine INotifyDataErrorInfo -Validierungen an. Die Textfelder werden in XAML wie folgt beschrieben:

<TextBox Text="{x:Bind ViewModel.Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Und wir verwenden hier ReactiveValidationObject als Implementierung von INotifyDataErrorInfo .

@worldbeater Dies ist nur in den neuesten Vorschauen von WinUI3 verfügbar, verwenden Sie das?

Danke @stevenbrix! Werde WinUI3 ausprobieren. Freut mich zu hören, dass sich INotifyDataErrorInfo und UWP endlich anfreunden ✨

@worldbeater , es befindet sich noch in der Vorschauphase, daher würden wir gerne Ihr Feedback dazu erhalten! 💪

@worldbeater übrigens, docs sagt, dass es auf UWP 10.0 verfügbar ist, aber es bedeutet nicht, dass es von ihm unterstützt wird. Die Dokumentation ist nicht klar genug.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen