Strona główna TECH .Net WPF MVVM PasswordBox Binding

WPF MVVM PasswordBox Binding

0
WPF MVVM PasswordBox Binding

Jak już wspominałem w jednym z  postów, bardzo odpowiada mi pełna separacja UI od reszty kodu jaką zapewnia wzorzec MVVM i doceniam w pełni jego zalety. Czasem jednak pojawia się klasyczne „g..no w szprychy” podczas jakieś prostej do wykonania w code-behind czynności.

Dzisiaj, podczas pracy nad desktopową aplikacją do robota pojawił się problem z bindigiem hasła z PasswordBox-a.  O ile w przypadku TextBox-a nie ma z  tym żadnego problemu, to w przypadku PasswordBox własność Password nie jest własnością zależną (DependencyProperty) więc zwykły binding nie wchodzi w grę.

Microsoft tłumaczy, że takie rozwiązanie podyktowane jest względami bezpieczeństwa. Jest to sensowne wytłumaczenie, ze względu na to, że własności zależne są zarządzane centralnie i w konsekwencji tego stają się one publiczne. W związku z tym faktem hasło trzymane jest w zmiennej typu SecureString. Niestety PasswordBox nie zezwala też na dostęp do tej zmiennej – a szkoda, bo binding mógłby być wtedy dużo prostszy przy zachowaniu hasła nadal w postaci zakodowanej.

Nie mniej jednak problem trzeba jakoś rozwiązać. Zacząłem poszukiwania i po przebrnięciu przez sporo propozycji (z ogromną ilością kodu – jak to zwykle w takich przypadkach w MVVM) znalazłem rozwiązanie satysfakcjonujące w tym blog poście.

Rozwiązanie polega na przygotowaniu dodatkowej klasy wspomagającej binding hasła za pomocą własności dołączanych. To rozwiązanie jest o tyle fajne, że klasę można z powodzeniem użyć w kolejnych projektach, a  nie wymaga też ono dużo dodatkowego kodu Xaml.

Pełny kod klasy jest oczywiście dostępny w poście  podlinkowanym powyżej, natomiast wykorzystanie jest bardzo proste:

<PasswordBox Name="NetworkPassword" 
             controls:TextBoxHelper.Watermark="Network password" 
             viewHelpers:PasswordBoxAssistant.BindPassword="true" 
             viewHelpers:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, 
                                                             UpdateSourceTrigger=PropertyChanged}"/>

Oczywiście w ViewModel-u trzeba utworzyć publiczną własność, którą będziemy bindować.

ZOSTAW ODPOWIEDŹ

Proszę wpisać swój komentarz!
Proszę podać swoje imię tutaj