Ich bin auf ein Problem mit der Bindung an ein P gestoßen asswordBox
. Es scheint ein Sicherheitsrisiko zu sein, aber ich verwende das MVVM-Muster, daher möchte ich dies umgehen. Ich habe hier einen interessanten Code gefunden (hat jemand diesen oder einen ähnlichen Code verwendet?)
http://www.wpftutorial.net/PasswordBox.html
Es sieht technisch gut aus, aber ich bin mir nicht sicher, wie ich das Passwort abrufen soll.
Ich habe grundsätzlich Eigenschaften in meinem LoginViewModel
für Username
und Password
. Username
ist in Ordnung und funktioniert so wie es ist TextBox
.
Ich habe den obigen Code wie angegeben verwendet und diesen eingegeben
<PasswordBox ff:PasswordHelper.Attach="True"
ff:PasswordHelper.Password="{Binding Path=Password}" Width="130"/>
Als ich das PasswordBox
als TextBox
und Binding Path=Password
dann hatte, wurde die Eigenschaft in meinem LoginViewModel
aktualisiert.
Mein Code ist sehr einfach, im Grunde habe ich einen Command
für meinen Button
. Wenn ich drücke, CanLogin
wird es aufgerufen und wenn es true zurückgibt, ruft es auf Login
.
Sie können sehen, dass ich meine Immobilie Username
hier überprüfe , was großartig funktioniert.
In Login
sende ich an meinen Dienst ein Username
und Password
, Username
enthalte Daten von meinem View
aber Password
istNull|Empty
private DelegateCommand loginCommand;
public string Username { get; set; }
public string Password { get; set; }
public ICommand LoginCommand
{
get
{
if (loginCommand == null)
{
loginCommand = new DelegateCommand(
Login, CanLogin );
}
return loginCommand;
}
}
private bool CanLogin()
{
return !string.IsNullOrEmpty(Username);
}
private void Login()
{
bool result = securityService.IsValidLogin(Username, Password);
if (result) { }
else { }
}
Das mache ich
<TextBox Text="{Binding Path=Username, UpdateSourceTrigger=PropertyChanged}"
MinWidth="180" />
<PasswordBox ff:PasswordHelper.Attach="True"
ff:PasswordHelper.Password="{Binding Path=Password}" Width="130"/>
Ich habe meine TextBox
, ist das kein Problem, aber in meiner ViewModel
das Password
ist leer.
Mache ich etwas falsch oder verpasse ich einen Schritt?
Ich habe einen Haltepunkt gesetzt und sicher genug, dass der Code in die statische Hilfsklasse eingeht, aber er aktualisiert meinen Password
in meinem nie ViewModel
.
Antworten:
Entschuldigung, aber du machst es falsch.
Personen sollten die folgenden Sicherheitsrichtlinien auf die Innenseite ihrer Augenlider tätowieren lassen:
Bewahren Sie niemals Klartext-Passwörter im Speicher auf.
Der Grund, warum WPF / Silverlight
PasswordBox
keinen DP für diePassword
Eigenschaft verfügbar macht, ist sicherheitsrelevant.Wenn WPF / Silverlight einen DP dafür behalten
Password
würde, müsste das Framework das Passwort selbst unverschlüsselt im Speicher behalten. Was als ziemlich lästiger Sicherheitsangriffsvektor angesehen wird. DerPasswordBox
verwendet verschlüsselten Speicher (sozusagen) und der einzige Weg, auf das Passwort zuzugreifen, ist über die CLR-Eigenschaft.Ich würde vorschlagen, dass Sie beim Zugriff auf die
PasswordBox.Password
CLR-Eigenschaft darauf verzichten, sie in eine Variable oder als Wert für eine Eigenschaft zu platzieren.Das Speichern Ihres Kennworts im Klartext im RAM des Client-Computers ist ein Sicherheits-Nein-Nein.
Also loswerden, dass
public string Password { get; set; }
du da oben bist.Wenn Sie darauf zugreifen
PasswordBox.Password
, holen Sie es einfach heraus und senden Sie es so schnell wie möglich an den Server. Behalten Sie den Wert des Kennworts nicht bei und behandeln Sie es nicht wie jeden anderen Clientcomputertext. Bewahren Sie keine Klartextkennwörter im Speicher auf.Ich weiß, dass dies das MVVM-Muster bricht, aber Sie sollten sich niemals an
PasswordBox.Password
Attached DP binden , Ihr Passwort im ViewModel oder anderen ähnlichen Spielereien speichern.Wenn Sie nach einer überarchitekten Lösung suchen, gehen Sie wie folgt vor:
1. Erstellen Sie die
IHavePassword
Schnittstelle mit einer Methode, die den Kennwort-Klartext zurückgibt.2. Lassen Sie Ihr
UserControl
Gerät eineIHavePassword
Schnittstelle implementieren .3. Registrieren Sie die
UserControl
Instanz bei Ihrem IoC als Implementierung derIHavePassword
Schnittstelle.4. Wenn eine Serveranforderung stattfindet, für die Ihr Kennwort erforderlich ist, rufen Sie Ihr IoC für die
IHavePassword
Implementierung an und erhalten Sie erst dann das begehrte Kennwort.Nur meine Meinung dazu.
- Justin
quelle
Meine 2 Cent:
Ich habe einmal einen typischen Anmeldedialog (Benutzer- und Passwortfelder sowie "Ok" -Schaltfläche) mit WPF und MVVM entwickelt. Ich habe das Problem mit der Passwortbindung gelöst, indem ich einfach das PasswordBox-Steuerelement selbst als Parameter an den Befehl übergeben habe, der an die Schaltfläche "OK" angehängt ist. Also in der Ansicht hatte ich:
Im ViewModel
Execute
lautete die Methode des angehängten Befehls wie folgt:Dies verstößt leicht gegen das MVVM-Muster, da das ViewModel jetzt etwas über die Implementierung der Ansicht weiß, aber in diesem speziellen Projekt könnte ich es mir leisten. Hoffe, es ist auch für jemanden nützlich.
quelle
Vielleicht fehlt mir etwas, aber es scheint, als ob die meisten dieser Lösungen die Dinge überkomplizieren und sichere Praktiken beseitigen.
Diese Methode verstößt nicht gegen das MVVM-Muster und gewährleistet vollständige Sicherheit. Ja, technisch gesehen ist es Code dahinter, aber es ist nichts weiter als eine "Sonderfall" -Bindung. Das ViewModel hat noch keine Kenntnisse über die View-Implementierung, was meiner Meinung nach der Fall ist, wenn Sie versuchen, die PasswordBox an das ViewModel zu übergeben.
Code Behind! = Automatische MVVM-Verletzung. Es hängt alles davon ab, was Sie damit machen. In diesem Fall codieren wir eine Bindung nur manuell, sodass sie als Teil der UI-Implementierung betrachtet wird und daher in Ordnung ist.
Im ViewModel nur eine einfache Eigenschaft. Ich habe es "nur schreiben" gemacht, da es aus keinem Grund erforderlich sein sollte, es von außerhalb des ViewModel abzurufen, aber es muss nicht sein. Beachten Sie, dass es sich um einen SecureString handelt, nicht nur um eine Zeichenfolge.
In der xaml richten Sie einen PasswordChanged-Ereignishandler ein.
Im Code dahinter:
Bei dieser Methode bleibt Ihr Kennwort jederzeit in einem SecureString und bietet daher maximale Sicherheit. Wenn Sie sich wirklich nicht um die Sicherheit kümmern oder das Klartextkennwort für eine nachgeschaltete Methode benötigen, die dies erfordert (Hinweis: Die meisten .NET-Methoden, für die ein Kennwort erforderlich ist, unterstützen auch eine SecureString-Option, sodass Sie möglicherweise kein Klartextkennwort benötigen Selbst wenn Sie glauben, dass Sie dies tun, können Sie stattdessen einfach die Password-Eigenschaft verwenden. So was:
(ViewModel-Eigenschaft)
(Code dahinter)
Wenn Sie die Dinge stark typisieren möchten, können Sie die (dynamische) Besetzung durch die Oberfläche Ihres ViewModel ersetzen. Aber wirklich, "normale" Datenbindungen sind auch nicht stark typisiert, also ist es keine so große Sache.
Das Beste von allen Welten: Ihr Passwort ist sicher, Ihr ViewModel hat nur eine Eigenschaft wie jede andere Eigenschaft und Ihre Ansicht ist eigenständig, ohne dass externe Referenzen erforderlich sind.
quelle
Sie können diese XAML verwenden:
Und dieser Befehl führt die Methode aus:
quelle
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=PasswordBox}}"
(Hinweis: nichtRelativeSource Self
).Das funktioniert gut für mich.
quelle
ICommand
im Ansichtsmodell implementiert ist, würde diese Lösung das MVVM-Muster verletzen.Eine einfache Lösung ohne Verletzung des MVVM-Musters besteht darin, ein Ereignis (oder einen Delegaten) in das ViewModel einzuführen, das das Kennwort erntet.
Im ViewModel :
public event EventHandler<HarvestPasswordEventArgs> HarvestPassword;
mit diesen EventArgs:
Abonnieren Sie in der Ansicht das Ereignis beim Erstellen des ViewModel und geben Sie den Kennwortwert ein.
Wenn Sie im ViewModel das Kennwort benötigen, können Sie das Ereignis auslösen und das Kennwort von dort abrufen:
quelle
WeakEventManager<TEventSource, TEventArgs>
, um Speicherverluste zu vermeiden. Oft hat die Ansicht nicht die gleiche Lebensdauer wie das Ansichtsmodell.WeakEventManager<IViewModel, EventArgs>.AddHandler(iViewModelInstance, nameof(IViewModel.Event), eventHandlerMethod);
Ich habe viel Zeit damit verbracht, nach verschiedenen Lösungen zu suchen. Ich mochte die Idee des Dekorateurs nicht, Verhaltensweisen bringen die Validierungs-Benutzeroberfläche durcheinander, Code dahinter ... wirklich?
Das Beste ist, sich an eine benutzerdefinierte angehängte Eigenschaft zu halten und sie
SecureString
in Ihrem Ansichtsmodell an Ihre Eigenschaft zu binden . Bewahren Sie es so lange wie möglich dort auf. Wenn Sie schnellen Zugriff auf das einfache Kennwort benötigen, konvertieren Sie es vorübergehend mit dem folgenden Code in eine unsichere Zeichenfolge:Stellen Sie sicher, dass Sie dem GC erlauben, Ihr UI-Element zu erfassen. Widerstehen Sie daher dem Drang, einen statischen Ereignishandler für das
PasswordChanged
Ereignis auf dem zu verwendenPasswordBox
. Ich habe auch eine Anomalie entdeckt, bei der das Steuerelement die Benutzeroberfläche nicht aktualisiert hat, als dieSecurePassword
Eigenschaft zum Einrichten verwendet wurde. Deshalb kopiere ichPassword
stattdessen das Kennwort in .Und die XAML-Nutzung:
Meine Eigenschaft im Ansichtsmodell sah folgendermaßen aus:
Das
RequiredSecureString
ist nur ein einfacher benutzerdefinierter Validator, den die folgende Logik:Hier hast du es. Eine vollständige und getestete reine MVVM-Lösung.
quelle
Ich habe hier eine GIST gepostet , die ein bindbares Passwortfeld ist.
quelle
ContentControl
Sie können dann einfach eine PasswordBox als Inhalt und Stil verwenden, der in XAML nach Ihren Wünschen passt. Der Zweck vonContentControl
ist nur, dasPasswordChanged
Ereignis zu abonnieren und eine in zwei Richtungen bindende Eigenschaft freizulegen. Alles in allem sind es 65 Codezeilen und so ziemlich das, was diese Dekorationsklasse macht. Siehe hier für meinen Kern der folgenden gist.github.com/leidegre/c7343b8c720000fe3132Diese Implementierung ist etwas anders. Sie übergeben ein Kennwortfeld an die Ansicht durch Bindung einer Eigenschaft in ViewModel. Es werden keine Befehlsparameter verwendet. Das ViewModel ignoriert die Ansicht. Ich habe ein VB vs 2010-Projekt, das von SkyDrive heruntergeladen werden kann. Wpf MvvM PassWordBox Example.zip https://skydrive.live.com/redir.aspx?cid=e95997d33a9f8d73&resid=E95997D33A9F8D73!511
Die Art und Weise, wie ich PasswordBox in einer Wpf-MvvM-Anwendung verwende, ist ziemlich simpel und funktioniert gut für mich. Das bedeutet nicht, dass ich denke, dass es der richtige oder der beste Weg ist. Es ist nur eine Implementierung von Using PasswordBox und dem MvvM-Muster.
Grundsätzlich erstellen Sie eine öffentliche schreibgeschützte Eigenschaft, an die die Ansicht als PasswordBox (das eigentliche Steuerelement) gebunden werden kann. Beispiel:
Ich benutze ein Hintergrundfeld, um die Eigeninitialisierung der Eigenschaft durchzuführen.
Dann binden Sie von Xaml aus den Inhalt eines ContentControls oder eines Steuercontainers. Beispiel:
Von dort aus haben Sie die volle Kontrolle über die Passwortbox. Ich verwende auch einen PasswordAccessor (nur eine Funktion der Zeichenfolge), um den Passwortwert beim Anmelden zurückzugeben oder für was auch immer Sie das Passwort möchten. Im Beispiel habe ich eine öffentliche Eigenschaft in einem generischen Benutzerobjektmodell. Beispiel:
Im Benutzerobjekt ist die Kennwortzeichenfolgeeigenschaft ohne Sicherungsspeicher schreibgeschützt. Sie gibt lediglich das Kennwort aus der Kennwortbox zurück. Beispiel:
Dann stelle ich im ViewModel sicher, dass der Accessor erstellt und auf die PasswordBox.Password-Eigenschaft 'Beispiel:
Wenn ich die Kennwortzeichenfolge für die Anmeldung sagen muss, erhalte ich nur die Eigenschaft User Objects Password, die die Funktion wirklich aufruft, um das Kennwort abzurufen und zurückzugeben. Dann wird das tatsächliche Kennwort nicht vom Benutzerobjekt gespeichert. Beispiel: wäre im ViewModel
Das sollte es tun. Das ViewModel benötigt keine Kenntnisse über die Steuerelemente der Ansicht. Die Ansicht wird nur an die Eigenschaft im ViewModel gebunden, nicht anders als die Ansicht, die an ein Bild oder eine andere Ressource gebunden ist. In diesem Fall ist diese Ressource (Eigenschaft) zufällig eine Benutzersteuerung. Es ermöglicht Tests, während das ViewModel die Eigenschaft erstellt und besitzt und die Eigenschaft unabhängig von der Ansicht ist. Was die Sicherheit betrifft, weiß ich nicht, wie gut diese Implementierung ist. Bei Verwendung einer Funktion wird der Wert jedoch nicht in der Eigenschaft selbst gespeichert, auf die die Eigenschaft gerade zugreift.
quelle
Um das OP-Problem zu lösen, ohne die MVVM zu beschädigen, würde ich einen benutzerdefinierten Wertekonverter und einen Wrapper für den Wert (das Kennwort) verwenden, der aus dem Kennwortfeld abgerufen werden muss.
Im Ansichtsmodell:
Da das Ansichtsmodell verwendet wird
IWrappedParameter<T>
, muss es keine Kenntnisse überPasswordBoxWrapper
oder habenPasswordBoxConverter
. Auf diese Weise können Sie dasPasswordBox
Objekt vom Ansichtsmodell isolieren und das MVVM-Muster nicht beschädigen.In der Ansicht:
quelle
Obwohl ich der Meinung bin, dass es wichtig ist, das Speichern des Kennworts an keiner Stelle zu vermeiden, muss ich dennoch die Möglichkeit haben, das Ansichtsmodell ohne Ansicht zu instanziieren und meine Tests dagegen auszuführen.
Die Lösung, die für mich funktioniert hat, bestand darin, die Funktion PasswordBox.Password beim Ansichtsmodell zu registrieren und sie beim Ausführen des Anmeldecodes vom Ansichtsmodell aufrufen zu lassen.
Dies tut bedeutet eine Zeile Code in der Code - Behind - Ansicht.
Also, in meiner Login.xaml habe ich
und in Login.xaml.cs habe ich
dann habe ich in LoginViewModel.cs den PasswordHandler definiert
und wenn eine Anmeldung erforderlich ist, ruft der Code den Handler auf, um das Kennwort aus der Ansicht abzurufen ...
Auf diese Weise kann ich beim Testen des Ansichtsmodells PasswordHandler einfach auf eine anonyme Methode setzen, mit der ich das Kennwort angeben kann, das ich im Test verwenden möchte.
quelle
Ich dachte, ich würde meine Lösung in die Mischung werfen, da dies ein so häufiges Problem ist ... und es immer gut ist, viele Optionen zu haben.
Ich habe einfach ein
PasswordBox
in ein eingewickeltUserControl
und ein implementiertDependencyProperty
, um binden zu können. Ich tue alles, um zu vermeiden, dass Klartext im Speicher gespeichert wird, sodass alles über aSecureString
und diePasswordBox.Password
Eigenschaft erfolgt. Während derforeach
Schleife wird jedes Zeichen freigelegt, aber es ist sehr kurz. Ehrlich gesagt, wenn Sie sich Sorgen machen, dass Ihre WPF-Anwendung durch diese kurze Exposition gefährdet wird, haben Sie größere Sicherheitsprobleme, die behoben werden sollten.Das Schöne daran ist, dass Sie keine MVVM-Regeln brechen, auch nicht die "puristischen", da dies eine ist
UserControl
und es daher erlaubt ist, Code-Behind zu haben. Wenn Sie es verwenden, können Sie eine reine Kommunikation zwischenView
undViewModel
ohneVideModel
Kenntnis eines TeilsView
oder der Quelle des Passworts haben. Stellen Sie einfach sicher, dass Sie anSecureString
Ihre gebunden sindViewModel
.BindablePasswordBox.xaml
BindablePasswordBox.xaml.cs (Version 1 - Keine Unterstützung für bidirektionale Bindungen.)
Verwendung von Version 1:
BindablePasswordBox.xaml.cs (Version 2 - Unterstützt die bidirektionale Bindung.)
Verwendung von Version 2:
quelle
if (Password != secure)
wird immer falsch sein, da SecureString nicht gleich überschreibt. Irgendwelche Gedanken?Sie können es mit angehängter Eigenschaft tun, sehen Sie es .. PasswordBox mit MVVM
quelle
Ich habe diese Methode verwendet und das Kennwortfeld übergeben, obwohl dies gegen die MVVM verstößt. Dies war für mich von wesentlicher Bedeutung, da ich für mein Login in meiner Shell ein Inhaltssteuerelement mit Datenvorlage verwendet habe, was eine komplexe Shell-Umgebung darstellt. Der Zugriff auf den Code hinter der Shell wäre also Mist gewesen.
Das Übergeben der Passwortbox ist meines Erachtens gleichbedeutend mit dem Zugriff auf die Kontrolle über den Code, soweit ich weiß. Ich stimme Passwörtern zu, speichere sie nicht im Speicher usw. In dieser Implementierung habe ich keine Eigenschaft für das Passwort im Ansichtsmodell.
Tastenbefehl
ViewModel
quelle
Für mich fühlen sich beide Dinge falsch an:
PasswordBox
Befehlsparameters als an das ViewModelDas Übertragen des SecurePassword (SecureString-Instanz), wie von Steve in CO beschrieben, scheint akzeptabel. ich bevorzuge
Behaviors
, hinterher zu codieren, und ich hatte auch die zusätzliche Anforderung, das Passwort vom Ansichtsmodell zurücksetzen zu können.Xaml (
Password
ist die ViewModel-Eigenschaft):Verhalten:
quelle
Für komplette Neulinge wie mich ist hier ein komplettes Arbeitsbeispiel der
Konamiman
oben vorgeschlagenen Vorschläge. DankeKonamiman
.XAML
ViewModel
quelle
Es ist eine angehängte Eigenschaft . Diese Art von Eigenschaft kann auf jede Art von Eigenschaft angewendet werden
DependencyObject
, nicht nur auf die Art, in der sie deklariert ist. Obwohl es in derPasswordHelper
statischen Klasse deklariert ist , wird es auf die angewendetPasswordBox
auf dem Sie es verwenden.Um diese angehängte Eigenschaft zu verwenden, müssen Sie sie nur an die
Password
Eigenschaft in Ihrem ViewModel binden :quelle
Ich habe getan wie:
XAML:
C #:
Für mich geht das!
quelle
Wie bereits erwähnt, sollte VM die Ansicht nicht kennen, aber das Übergeben der gesamten PasswordBox scheint der einfachste Ansatz zu sein. Anstatt übergebene Parameter an PasswordBox zu übertragen, verwenden Sie Reflection, um die Password-Eigenschaft daraus zu extrahieren. In diesem Fall erwartet VM eine Art Kennwortcontainer mit der Eigenschaft Kennwort (ich verwende RelayCommands von MVMM Light-Toolkit):
Es kann leicht mit einer anonymen Klasse getestet werden:
quelle
In Windows Universal App
Sie können diesen Code mit der Eigenschaft "Passwort" und der Bindung mit der modelView verwenden
quelle
Wenn Sie sich der Risiken bewusst sind, die diese Implementierung mit sich bringt, fügen Sie einfach Mode = OneWayToSource hinzu, damit das Kennwort mit Ihrem ViewModel synchronisiert wird .
XAML
quelle
OneWayToSource
?Hier ist meine Meinung dazu:
Die Verwendung einer angehängten Eigenschaft zum Binden des Kennworts macht den Zweck der Sicherung des Kennworts zunichte. Die Kennworteigenschaft eines Kennwortfelds ist aus einem bestimmten Grund nicht bindbar.
Wenn Sie das Kennwortfeld als Befehlsparameter übergeben, wird das ViewModel auf das Steuerelement aufmerksam. Dies funktioniert nicht, wenn Sie planen, Ihr ViewModel plattformübergreifend wiederverwendbar zu machen. Machen Sie Ihre VM nicht auf Ihre Ansicht oder andere Steuerelemente aufmerksam.
Ich denke nicht, dass die Einführung einer neuen Eigenschaft, einer Schnittstelle, das Abonnieren von Ereignissen mit geändertem Passwort oder anderen komplizierten Dingen für eine einfache Aufgabe der Bereitstellung des Passworts erforderlich ist.
XAML
Code dahinter - Die Verwendung von Code dahinter verstößt nicht unbedingt gegen MVVM. Solange Sie keine Geschäftslogik einfügen.
ViewModel
quelle
Eine Lösung für die PasswordBox finden Sie in der ViewModel-Beispielanwendung des WPF Application Framework (WAF). -Projekts.
Justin hat jedoch recht. Übergeben Sie das Kennwort nicht als Nur-Text zwischen View und ViewModel. Verwenden Sie stattdessen SecureString (siehe MSDN PasswordBox).
quelle
Ich habe eine Authentifizierungsprüfung verwendet, gefolgt von einem Sub, das von einer Mediator-Klasse in der Ansicht aufgerufen wurde (die auch eine Authentifizierungsprüfung implementiert), um das Kennwort in die Datenklasse zu schreiben.
Es ist keine perfekte Lösung; Es hat jedoch mein Problem behoben, dass das Passwort nicht verschoben werden konnte.
quelle
Ich verwende eine prägnante MVVM-freundliche Lösung, die noch nicht erwähnt wurde. Zuerst benenne ich die PasswordBox in XAML:
Dann füge ich dem View-Konstruktor einen einzelnen Methodenaufruf hinzu:
Und das ist es. Das Ansichtsmodell erhält eine Benachrichtigung, wenn es über DataContext an eine Ansicht angehängt wird, und eine weitere Benachrichtigung, wenn es getrennt wird. Der Inhalt dieser Benachrichtigung kann über die Lambdas konfiguriert werden. In der Regel handelt es sich jedoch nur um einen Setter- oder Methodenaufruf für das Ansichtsmodell, bei dem die problematische Steuerung als Parameter übergeben wird.
Es kann sehr einfach MVVM-freundlich gemacht werden, indem die Ansicht die Benutzeroberfläche anstelle von untergeordneten Steuerelementen verfügbar macht.
Der obige Code stützt sich auf Hilfsklasse auf meinem Blog veröffentlicht.
quelle
Ich habe ewig versucht, dies zum Laufen zu bringen. Am Ende habe ich aufgegeben und nur das PasswordBoxEdit von DevExpress verwendet.
Es ist die einfachste Lösung aller Zeiten, da es das Binden ermöglicht, ohne schreckliche Tricks zu machen.
Lösung auf der DevExpress-Website
Ich bin in keiner Weise mit DevExpress verbunden.
quelle
;) einfach!
quelle
Es ist sehr einfach . Erstellen Sie eine weitere Eigenschaft für das Kennwort und binden Sie diese mit TextBox
Alle Eingabevorgänge werden jedoch mit der tatsächlichen Kennworteigenschaft ausgeführt
private Zeichenfolge _Password;
öffentlicher String Passwort {get {return _Password; }}
quelle
Nun, meine Antwort ist einfacher, nur für das MVVM-Muster
im Klassenansichtsmodell
Die Kennworteigenschaft der von win bereitgestellten PasswordBox oder der von XCeedtoolkit bereitgestellten WatermarkPasswordBox generiert ein RoutedEventArgs, damit Sie es binden können.
jetzt in xmal view
oder
quelle
Sende ein
SecureString
an das Ansichtsmodell mit einem angehängten Verhalten undICommand
Bei der Implementierung von MVVM ist an Code-Behind nichts auszusetzen. MVVM ist ein Architekturmuster, das darauf abzielt, die Ansicht von der Modell- / Geschäftslogik zu trennen. MVVM beschreibt, wie dieses Ziel auf reproduzierbare Weise erreicht werden kann (das Muster). Es sind keine Implementierungsdetails wichtig, z. B. wie Sie die Ansicht strukturieren oder implementieren. Es zeichnet nur die Grenzen und definiert, was die Ansicht, das Ansichtsmodell und das Modell in Bezug auf die Terminologie dieses Musters ist.
MVVM kümmert sich nicht um die Sprache (XAML oder C #) oder den Compiler (
partial
Klassen). Sprachunabhängigkeit ist ein obligatorisches Merkmal eines Entwurfsmusters - es muss sprachneutral sein.Code-Behind hat jedoch einige Nachteile, z. B. dass es schwieriger wird, Ihre UI-Logik zu verstehen, wenn sie wild zwischen XAML und C # verteilt ist. Die wichtigste Implementierung von UI-Logik oder Objekten wie Vorlagen, Stilen, Triggern, Animationen usw. in C # ist jedoch sehr komplex und hässlich / weniger lesbar als die Verwendung von XAML. XAML ist eine Auszeichnungssprache, die Tags und Verschachtelungen verwendet, um die Objekthierarchie zu visualisieren. Das Erstellen einer Benutzeroberfläche mit XAML ist sehr praktisch. Obwohl es Situationen gibt, in denen Sie die UI-Logik in C # (oder Code-Behind) implementieren können. Der Umgang mit
PasswordBox
ist ein Beispiel.Aus diesen Gründen ist die Behandlung des
PasswordBox
im Code-Behind durch die Behandlung desPasswordBox.PasswordChanged
, keine Verletzung des MVVM-Musters.Ein klarer Verstoß wäre, ein Steuerelement (das
PasswordBox
) an das Ansichtsmodell zu übergeben. Viele Lösungen empfehlen dies, z. B. das Übergeben der Instanz desPasswordBox
asICommand.CommandParameter
an das Ansichtsmodell. Offensichtlich eine sehr schlechte und unnötige Empfehlung.Wenn Sie sich nicht für die Verwendung von C # interessieren, sondern nur Ihre CodeBehind-Datei sauber halten oder einfach eine Verhaltens- / UI-Logik kapseln möchten, können Sie jederzeit angehängte Eigenschaften verwenden und ein angehängtes Verhalten implementieren.
Im Gegensatz zu dem berüchtigten, weit verbreiteten Helfer, der die Bindung an das Nur-Text-Passwort ermöglicht (wirklich schlechtes Anti-Pattern- und Sicherheitsrisiko), verwendet dieses Verhalten ein
ICommand
, um das PasswortSecureString
für das Ansichtsmodell zu senden , wann immer dasPasswordBox
ausgelöst wirdPasswordBox.PasswordChanged
Ereignis .MainWindow.xaml
ViewModel.cs
PasswordBox.cs
quelle