Pages

Monday, 23 June 2008

WPF PasswordBox and Data binding

Like Charles Petzold, I am something of a Xamlholic: I'll try for hours to find a way of expressing my UI in pure XAML, rather than pollute its purity with C# code, even if the code could go in a code-behind file. This addiction is largely driven by WPF's fantastic support for Data Binding which lets anything in the UI be data-bound to anything else. Well, almost anything in the UI. Just occasionally I find myself having to fall back on property setters and getters, poking data into controls then sucking it back again, the way Windows Forms made me earn my living. One control which nearly had me beat was PasswordBox.

PasswordBox is what you need whenever you want to mask the characters as a user types them: for some reason, WPF's standard TextBox doesn't support that scenario. Now PasswordBox has, as you'd expect, a Password property that allows you to get and set the password. However, it's a plain CLR property rather than a Dependency Property, so it doesn't support being the target of a Data binding.

Ben Westbrook of Microsoft explains in a forum post that it was not exposed as a Dependency Property for security reasons. The values of Dependency Properties are managed centrally by the Dependency Property sub-system so that it can handle all the data-binding and cool animation stuff (animating a password - now that would be interesting!); the consequence of this is that the data effectively becomes public property. With something as sensitive as a password it's reasonable that a control (like PasswordBox) would want to keep the data closer to its chest. So internally the PasswordBox stores the password in a good old field, and in fact holds it using a SecureString - a string that is automatically encrypted in memory and obliterated when no longer needed; if you Reflector PasswordBox you'll see that the Password property setter stuffs any value you set into a SecureString, and the getter reads it out for you; PasswordBox appends characters one by one to the SecureString as you type them, so the password is never stored as clear text until you retrieve it through the Password property.

As an aside, one thing I don't understand about the design is why PasswordBox doesn't provide a property to access the password as a SecureString, and so preserve the encryption? The act of retrieving the password through the Password property (as you'll have to do at some point in order to use the password) will turn it into clear text, and then you'll surely loose most of the benefit of ever having it encrypted? Perhaps someone from Microsoft can explain?

Update: As Ray pointed out in the comments, Microsoft have now (as from .Net 3.5 SP1) added a SecurePassword property to PasswordBox; it's still not a DependencyProperty though.

Anyhow, let's get to the point. Sometimes your main interest in using a PasswordBox is to have the password text masked as it's typed, and encryption isn't really an issue. In this case its a shame not to be able to use data binding.

Fortunately, WPF has the concept of Attached Properties that allow controls to be extended very easily. I've knocked up a class that extends PasswordBox with an Attached Property that lets you data bind the password. You use it as shown below (note particularly the additional xmlns element you need to add to the root element in your XAML):

<Page xmlns:ff="clr-namespace:FunctionalFun.UI">
  <!-- [Snip] -->
  <PasswordBox x:Name="PasswordBox"
      ff:PasswordBoxAssistant.BindPassword="true"  ff:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

</Page>

And here's the code. Very simple; setting the BindPassword property causes the code to start listening to the PasswordChanged event on the PasswordBox: whenever there is a change the code pushes the new value into the Attached Property BoundPassword which you can specify a binding for. It also takes care of the other direction, going from BoundPassword (whenever your the bound source property changes) into the PasswordBox. The only complication is making sure the whole thing doesn't get recursive and blow up: that's what the private attached property UpdatingPassword is for.

using System.Windows;
using System.Windows.Controls;

namespace FunctionalFun.UI
{
  public static class PasswordBoxAssistant
  {
      public static readonly DependencyProperty BoundPassword =
          DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxAssistant), new PropertyMetadata(string.Empty, OnBoundPasswordChanged));

      public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
          "BindPassword", typeof (bool), typeof (PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged));

      private static readonly DependencyProperty UpdatingPassword =
          DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false));

      private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
          PasswordBox box = d as PasswordBox;

          // only handle this event when the property is attached to a PasswordBox
          // and when the BindPassword attached property has been set to true
          if (d == null || !GetBindPassword(d))
          {
              return;
          }

          // avoid recursive updating by ignoring the box's changed event
          box.PasswordChanged -= HandlePasswordChanged;

          string newPassword = (string)e.NewValue;

          if (!GetUpdatingPassword(box))
          {
              box.Password = newPassword;
          }

          box.PasswordChanged += HandlePasswordChanged;
      }

      private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
      {
          // when the BindPassword attached property is set on a PasswordBox,
          // start listening to its PasswordChanged event

          PasswordBox box = dp as PasswordBox;

          if (box == null)
          {
              return;
          }

          bool wasBound = (bool)(e.OldValue);
          bool needToBind = (bool)(e.NewValue);

          if (wasBound)
          {
              box.PasswordChanged -= HandlePasswordChanged;
          }

          if (needToBind)
          {
              box.PasswordChanged += HandlePasswordChanged;
          }
      }

      private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
      {
          PasswordBox box = sender as PasswordBox;

          // set a flag to indicate that we're updating the password
          SetUpdatingPassword(box, true);
          // push the new password into the BoundPassword property
          SetBoundPassword(box, box.Password);
          SetUpdatingPassword(box, false);
      }

      public static void SetBindPassword(DependencyObject dp, bool value)
      {
          dp.SetValue(BindPassword, value);
      }

      public static bool GetBindPassword(DependencyObject dp)
      {
          return (bool)dp.GetValue(BindPassword);
      }

      public static string GetBoundPassword(DependencyObject dp)
      {
          return (string)dp.GetValue(BoundPassword);
      }

      public static void SetBoundPassword(DependencyObject dp, string value)
      {
          dp.SetValue(BoundPassword, value);
      }

      private static bool GetUpdatingPassword(DependencyObject dp)
      {
          return (bool)dp.GetValue(UpdatingPassword);
      }

      private static void SetUpdatingPassword(DependencyObject dp, bool value)
      {
          dp.SetValue(UpdatingPassword, value);
      }
  }
}

Update: If you're trying to weigh up the security risks of using this method, take a look at Daniel D'Agostino's article where he shows how passwords in memory can be snooped.

103 comments:

  1. Hi,
    Line 23 : I Guess this must be something like:

    if(d == null || !GetBindPassword(d))
    {
    return;
    }

    Anyway, thanks for this post.
    Regards, Jeroen de Zeeuw

    ReplyDelete
  2. Jeroen,
    Thanks for spotting this. Blogger must have swallowed my pipe symbols!

    Should be fixed now.

    Sam

    ReplyDelete
  3. Hello, i use your code but my binding to Password property for a User. The field password is empty.
    Give me a simple example using PasswordBoxAssistant

    my email is btvent_d_est@yahoo.fr

    ReplyDelete
  4. thanks man,
    you saved my day,
    and my nerves....

    ReplyDelete
  5. I am also wondering if this helper was ever designed to get a saved password. Mine does not retrieve the string password it is bound to.

    ReplyDelete
  6. Eric,
    I'm not quite sure what you mean by a saved password. Could you elaborate? As far as I know, PasswordBox doesn't implement saving of passwords.

    Sam

    ReplyDelete
  7. Sam,
    My passwordbox is databound to a string property on an item within a collection using your helper. I would assume that when I reload that form, the passwordbox would Get that property and load it -- albeit masked. As of now it gives the impression that they have not entered a password.

    The passwordbox, with this helper, sets that property just fine -- it's just the get that I'm struggling with. I get an error in my output. "System.Windows.Data Error: 16 : Cannot get 'Password' value (type 'String') from '' (type 'AccountSettingsItem')."

    Any ideas? Thanks Sam.

    ReplyDelete
  8. Eric,
    The error suggests that the WPF is having trouble accessing the getter of the Password property on your collection item. Is it public? might it be throwing an exception? Have you tried putting a breakpoint on it to check it is hit?

    I've used this in a situation where we've saved the password, so my initial thought is that the problem doesn't lie with the PasswordBoxHelper.

    ReplyDelete
  9. Good point.

    Would you prefer to discuss this over email instead of cluttering the comments? My email is listed in my Blogger profile.

    ReplyDelete
  10. Just to wrap up the conversation with Eric: it appears that the property Eric was binding Password to was throwing an exception in its getter.

    ReplyDelete
  11. What about modifying the TextBox control to mask input. Would that be easier?

    ReplyDelete
  12. Anonymous,
    In general, sub-classing a control in WPF is harder and not as flexible as the approaches similar to the one shown here which provide an attached behaviour, and allow that to be composed into other controls.

    I believe I looked into masking TextBox input, and I don't think it was trivial.

    ReplyDelete
  13. Thanks for creating this solution and I totally agree with you on your comments about their statement that "PasswordBox.Password as DP = security issue". I think if someone wanted to read out the password, they can probably do that even without the DP. I also want to use PasswordBox only for hiding the password from the actual users.

    ReplyDelete
  14. Hey Sam, Kevin from (formerly) Disney here.
    This is going to come in very handy for my current project if I can convert this over to Silverlight :)

    Hope all is well across the pond!

    ReplyDelete
  15. That's cool. Thank you buddy.

    ReplyDelete
  16. In .NET 3.5 the PasswordBox control has a SecurePassword property to get the password as a SecureString.

    ReplyDelete
  17. @Ray: thanks for pointing that out. I've updated the article to mention that property.

    ReplyDelete
  18. Very useful piece of code when doing ViewModels. Thanks for posting this.

    ReplyDelete
  19. What level of attribution do you require? Is a source code comment sufficient, or do you require something more?

    ReplyDelete
  20. A source code comment with a link back to the post is fine. Nice to know my code is in use!

    ReplyDelete
  21. In OnBoundPasswordChanged, I think you mean to check if box is null, not d.

    ReplyDelete
  22. Great code, just one question: is this possible in Silverlight?

    ReplyDelete
  23. Anonymous:
    If you're using Silverlight 3 you don't need this code: the Password property is a dependency property, so you can already Databind to it.

    ReplyDelete
  24. Great, this came in handy

    I'm working in WPF, and wanted to element-to-element bind the password. I know it's not as secure, but this is a reasonable way to do it.

    Thanks!

    ReplyDelete
  25. can anybody give it to me in vb.net. I am getting the error for first 2 declarations when i changed to vb.net

    ReplyDelete
  26. ok i got that issue in vb.net we can prefix with AddressOf keyword before OnBound...

    ReplyDelete
  27. Hi everyone i try to convert this to vb.net and i've created this code ( and it compiles fine with no errors but i having troubles in my xaml code) if anyone can help i am using it in a user control:


    Public Class PasswordBoxAssistant
    Public ReadOnly BoundPassword As DependencyProperty = _
    DependencyProperty.RegisterAttached("BoundPassword", GetType(String), GetType(PasswordBoxAssistant), New FrameworkPropertyMetadata(String.Empty, AddressOf OnBoundPasswordChanged))

    Public ReadOnly BindPassword As DependencyProperty = _
    DependencyProperty.RegisterAttached("BindPassword", GetType(Boolean), GetType(PasswordBoxAssistant), New PropertyMetadata(False, AddressOf OnBindPasswordChanged))

    Public ReadOnly UpdatingPassword As DependencyProperty = _
    DependencyProperty.RegisterAttached("UpdatingPassword", GetType(Boolean), GetType(PasswordBoxAssistant))

    Private Sub OnBoundPasswordChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    Dim box As PasswordBox = TryCast(d, PasswordBox)

    If box Is Nothing Or Not GetBindPassword(box) Then
    Return
    End If

    RemoveHandler box.PasswordChanged, AddressOf HandlePasswordChanged

    Dim newPassword As String = TryCast(e.NewValue, String)

    If Not GetUpdatingPassword(box) Then
    box.Password = newPassword
    End If

    AddHandler box.PasswordChanged, AddressOf HandlePasswordChanged
    End Sub

    Private Sub OnBindPasswordChanged(ByVal dp As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    Dim box As PasswordBox = TryCast(dp, PasswordBox)
    If box Is Nothing Then
    Return
    End If

    Dim wasBound As Boolean = e.OldValue
    Dim needToBind As Boolean = e.NewValue

    If wasBound Then
    RemoveHandler box.PasswordChanged, AddressOf HandlePasswordChanged
    End If

    If needToBind Then
    AddHandler box.PasswordChanged, AddressOf HandlePasswordChanged
    End If
    End Sub

    Private Sub HandlePasswordChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim box As PasswordBox = TryCast(sender, PasswordBox)
    SetUpdatingPassword(box, True)
    SetBoundPassword(box, box.Password)
    SetUpdatingPassword(box, False)
    End Sub

    Public Sub SetBindPassword(ByVal dp As DependencyObject, ByVal valor As Boolean)
    dp.SetValue(BindPassword, valor)
    End Sub

    Public Function GetBindPassword(ByVal dp As DependencyObject) As String
    Return dp.GetValue(BindPassword)
    End Function


    Public Function GetBoundPassword(ByVal dp As DependencyObject) As String
    Return dp.GetValue(BoundPassword)
    End Function

    Public Sub SetBoundPassword(ByVal dp As DependencyObject, ByVal valor As String)
    dp.SetValue(BoundPassword, valor)
    End Sub

    Public Function GetUpdatingPassword(ByVal dp As DependencyObject) As Boolean
    Return dp.GetValue(UpdatingPassword)
    End Function

    Public Sub SetUpdatingPassword(ByVal dp As DependencyObject, ByVal valor As Boolean)
    dp.SetValue(UpdatingPassword, valor)
    End Sub
    End Class

    Any help to cjtapiaa@hotmail.com

    ReplyDelete
  28. please anyone can explain how to use it in a user control wih wpf and vb net thanks

    ReplyDelete
  29. Thank you for this, it gave me just what I needed!

    ReplyDelete
  30. Excellent post. You're in my code now. :-)

    ReplyDelete
  31. Very useful - thank you!

    I think line 23 should read "if (box == null"

    ReplyDelete
  32. Did anyone manage to have that PasswordBoxAssistant working with VB.NET? I do have some issues in the .xaml portion when setting the properties for the PasswordBox. It does not recognize the BoundPassword and BindPasswork properties (or perhaps the class itself). I do have a namespace at the top of my usercontrol that is not giving me any error. Any though?

    ReplyDelete
  33. @Anonymous,
    Try changing the names of all the static DependencyProperty members to include "Property". E.g.

    public static readonly DependencyProperty BoundPasswordProperty =
    DependencyProperty.RegisterAttached("BoundPassword", typeof(string), ...);

    ReplyDelete
  34. @Sam,

    Thanks for the reply. Changing the name is not helping. I have a very simple solution working with C# but can't have the VB.NET equivalent working. I have a PasswordBoxAssistant class and a WPF window under the same project. Again, class compiles fine but when adding the namespace to the window, intellisense is not listing my PasswordBoxAssistant class (when it shows fine in C#). Have you manage to have it working in VB.NET? Thanks for your time

    ReplyDelete
  35. Very sorry, but I've never tried it in VB.Net.

    ReplyDelete
  36. Can't get the XAML to validate when using this. Even after adding the forgotten closing /PasswordBox tag. It claims the dependency properties are missing

    ReplyDelete
  37. Hi Sam,

    Congrats on this very clean piece of work!

    I used this class on a "create account" form and noted when used with two password controls (password + confirm password) on a form, both password controls were filled out as I entered a password in any ONE of the controls. I assume because we are listening for changes of the password property, any password control on the form will receive changes.

    Any idea on how to fix this behavior? Obviously I want these password boxes to act independently...

    Thanks!

    Doug

    ReplyDelete
  38. Doug, Interesting. I can't immediately think of a reason why this should be happenning. I'll have a look...

    ReplyDelete
  39. Hi Sam i'll like to know if this solution can be tried in a windowns form(wpf)?When i try the properties are not recognized as DependencyProperty.error is dependency property missing.i'm using c# i'm wondering if it's the same case as the Anonymous using vb.net?

    ReplyDelete
  40. Following issue on having logic working with VB.NET (27 May 2010 20:16). If you define the PasswordBoxAssistant as Public Module instead of a class it will work (since in C# the class is static).

    ReplyDelete
  41. Anonymous: thanks for updating us on that.

    ReplyDelete
  42. Very helpful thanks for sharing.

    ReplyDelete
  43. I created an example bindable password box (http://gist.github.com/468331) using the decorator pattern that is similar.

    ReplyDelete
  44. Taylor,
    Thanks for sharing that. The use of the decorator pattern is interesting. In my experience though, the attached behaviour approach gives more flexibility, as WPF allows behaviours to be composed more easily than decorators.

    ReplyDelete
  45. Hi Sam,
    I am trying to use your code in silverlight 2 but i get the following compile error

    1. the type or namespace name 'FrameworkPropertyMetadata' could not be found

    2. error in code line 15 No overload for method 'RegisterAttached' takes '3' argument.

    Your help and guidance will be much appreciated.

    Shuhed

    2. No over

    ReplyDelete
  46. Change FrameworkPropertyMetadata to PropertyMetadata. That should do it.

    ReplyDelete
  47. Hi Sam,

    Thanks for the quick response. I am getting error on this bit of code:

    private static readonly DependencyProperty UpdatingPassword =
    DependencyProperty.RegisterAttached( "UpdatingPassword", typeof( bool ), typeof( PasswordBoxAssistant ));

    Where RegisterAttached does not takes 3 argument. What is the fourth argument i should pass?

    Shuhed

    ReplyDelete
  48. Sorry, I should have check that part: use "new PropertyMetadata(false)".

    I've updated the code in the blog post so it should be compatible with Silverlight 2 now.

    ReplyDelete
  49. Hi Sam,

    I am getting the error in the XAML
    ff:PasswordBoxAssistant.BindPassword="True" ff:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

    I get error invalid attribute value in ff:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}". The bit its complaining is UpdateSourceTrigger=PropertyChanged. Is there anything i missed out? Thanks again for your great help. Shuhed

    ReplyDelete
  50. Just drop UpdateSourceTrigger=PropertyChanged from your code.

    ReplyDelete
  51. Thanks for again for you help. I found your article very good and keep on posting mate.

    Cheers
    Shuhed

    ReplyDelete
  52. Hi Sam,

    How can i get it working so that the passwordbox can load empty?

    Shuhed

    ReplyDelete
  53. Shuhed, I'm not quite sure what you mean by "load empty".

    ReplyDelete
  54. Sam,

    its ok. I've fixed the problem. Thanks.

    Shuhed

    ReplyDelete
  55. Validation not working on BoundPassword property. Any ways around?

    ReplyDelete
  56. Hi sam,

    I think I understand what shuhed means, for I seem to have the same pb :

    I have successfully used your helper till today. What I have now is this behaviour :
    1) every thing work fine
    2) at some point, I update the source of the binding to "" (empty string). The value in the passwordBox is updated fine to "" but...
    3) from this point, nothing works any more : I can type whatever I want in the passwordBox, it will not go through any of the handlers and no property is changed in the helper class
    4) if at some point I re-set the source of the binding to a string that is not empty, everything starts working fine again.

    I'm puzzled by this behaviour and have absolutely no clue as to what might be happening here. Help would be very much appreciated.

    and Shuhed, if you come back here, I'd like to know a bit more about your trouble/solution

    thanks in advance

    ReplyDelete
  57. never mind, I found what was the pb :

    I have to do every thing dynamically, so in c# rather than xaml, and I had omitted to translate in c# the "ff:PasswordBoxAssistant.BindPassword="true"" part of the xaml code.

    The issue was resolved by adding the following to my code : passwordBox.SetValue(PasswordHelper.AttachProperty, true);

    ("AttachProperty" being my version of your "BindPasswordProperty")

    I still don't understand how this triggered the aforementioned behaviour though, as there seems to be no direct link between the issue and the solution...

    thanks for your great help anyway, it's really sparing me some time and headaches...

    ReplyDelete
  58. This is great stuff. What would the implications be of binding to a SecureString property instead of a plain old string?

    I'm using a viewmodel, but would like to try to use the password as a SecureString.

    Thanks

    ReplyDelete
  59. @Rob,
    The question is, what are you going to do with password in your view model? Are you going to be passing it on to an API that accepts a SecureString? Or is it heading for an API that only accepts clear text?

    If it is eventually going to be clear text anyway, it's going to be easier to stick with a clear text data binding.

    Here's what you need to watch out for if you go down the SecureString route:

    1) SecureString is IDisposable: when you call the SecurePassword property on PasswordBox it returns a copy of its inner SecureString. But at what point will you dispose of this copy?

    2) As far as I can see, PasswordBox doesn't offer a means of setting the password programmatically
    apart from using clear text - the SecurePassword property is read-only. This means that your databinding can only be one way (from view back to view model).

    Hope that helps.

    ReplyDelete
  60. Thanks for your quick response Sam.

    I my case I will be persisting the password, so I figured that persisting it as a securestring might be the way to go.

    I know that there are ways to convert a securestring to a clear text string, so it would be possible to use your helper methods and then convert everything.

    So as far as I can tell, until Microsoft implements the securestring property as a dependancy property, there is no way to use passwordbox with databinding to a viewmodel pattern that doesn't expose the password as clear text at some point?

    Thanks

    ReplyDelete
  61. Rob,
    That would be my conclusion.

    Sam

    ReplyDelete
  62. Sam,

    Took me a little while to get my head around this, but now I have, it's exactly what I needed. Many thanks.

    Phil

    ReplyDelete
  63. Wow, how frustrating that it takes 50+ lines of fairly complex code to do something so simple. I'm all for keeping the UI free from C# code, but not at ANY cost.

    To save 2 or 3 lines of code in the UI, you'll add a ton of code somewhere else???

    ReplyDelete
  64. Hi Sam!
    I'm using PasswordBox, but i need detect the key enter and after execute the validation, any idea?

    ReplyDelete
  65. This comment has been removed by the author.

    ReplyDelete
  66. Hi anonymous, to detect the enter key:
    Anonymous:
    Just add this in your xaml:
    <PasswordBox KeyDown="OnKeyDown"
    And add this to your xaml.cs:
    private void OnKeyDown(object sender, KeyEventArgs e)
    {
    if (e.Key == Key.Enter)
    {
    Submit.Focus();
    var peer = new ButtonAutomationPeer(Submit);
    var invokeProvider = (IInvokeProvider)peer;
    invokeProvider.Invoke();
    }
    }

    ReplyDelete
  67. Nice article on using attached properties :)

    Just a quick question though, why would you just inherit from passwordbox and put these extensions of the class in that way. To me it seems that this static class you have is specific to password box and not a general use class of attached properties and functions.

    Thanks!

    ReplyDelete
  68. @Zach: I presume you mean "why would you NOT just inherit from passwordbox"?

    The reason is composability. If I implemented my extensions by inheriting from PasswordBox, and you also created some extensions by inheriting from PasswordBox, how would Joe Blogs go about using both our extensions?

    However, if we both use attached properties to define the behaviour, Joe Blogs can just give values to both our properties when he uses PasswordBox to activate the behaviours.

    ReplyDelete
  69. Hi Sam,

    very good work!

    But how can i bind ValidationRules?

    Thanks

    ReplyDelete
  70. Sam,

    Like Ali, i'm not able to use the IDataError interface to validate the password since then NotifyPropertyChanged isn't fired in my VM.

    ReplyDelete
  71. Just so you know, it looks like a javascript:void(0) somehow worked its way into your code.

    "private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)javascript:void(0)"

    ReplyDelete
  72. @Ross,
    Thanks for letting me know - I've corrected that now.

    ReplyDelete
  73. I am using this code, but I ran into a problem. I am also using Pages and NavigationService. Turns out the NavigationService blanks this password.

    So I have a call to the navigation service, and I have to save the password, and replace it afterwards. Thought I would let you know.

    Here are the details:
    WPF NavigationService blanks PasswordBox.Password, which breaks the MVVM PasswordHelper
    http://www.rhyous.com/2011/04/08/wpf-navigationservice-blanks-passwordbox-password-which-breaks-the-mvvm-passwordhelper/

    ReplyDelete
  74. As just a quick note, I believe you get a false positive error reported by ReShaper 5.1 using this code.

    I think this is fixed in 6 although I'm not in a position to test it at the moment.

    ReplyDelete
  75. Do I have your permission to use this code in my solution and modify it if necessary ?

    ReplyDelete
  76. Can any One Provide me a Database Password  Value Binding Steps Using this in c#

    ReplyDelete
  77. Man You Rock Like Hell. ( Extremly awsome )
    Thank You So Much !

    ReplyDelete
  78. Good stuff. One small change though, in your OnBoundPasswordChanged method, you should be null-checking "box" and checking if GetBindPassword of box is true.

    ReplyDelete
  79. hi, 
    awsome article, but where and how is this corrected? i just copied your code and the NavigationService still blanks my password.

    ReplyDelete
  80. I have been advised not to use System.Windows.Controls when you are trying to follow MVVM pattern. Do you agree with this statement? Since I am still learning MVVM pattern, I don’t know why.

    ReplyDelete
  81. Were you advised not to reference System.Windows.Controls in the ViewModel itself? That is a good principle to try and follow in general. You will, of course need to make use of those controls in your View (in Xaml). But your ViewModel should only concern itself with behaviour, not with how things look. It should communicate with the View almost exclusively using data binding and ICommands.

    ReplyDelete
  82. Hi! Great solution. I like it very much. Is there any way to also add some Binding.ValidationRules to it?

    ReplyDelete
  83. My comment that "I've corrected it" was aimed at Ross, not Jared :-)

    So, I've not made any changes to the way PasswordBox works with the NavigationService. If I understand Jared correctly, he solved his problem by stashing the value of the passsword box away before the NavigationService was invoked, and then restored it when his ViewModel was reloaded.

    ReplyDelete
  84. That was an excellent solution!

    ReplyDelete
  85. Hi,

    Thank you for this usefull piece of code.

    BoundPassword, BindPassword and UpdatingPassword should be respectilvly named BoundPasswordProperty, BindPasswordProperty and UpdatingPasswordProperty to avoid the "dependency property missing" problem in xaml.

    ReplyDelete
  86. Thanks very much for this excellent post (realizing that it's 3.5 years old... the Internets that keep on giving), this was exactly what I needed.

    ReplyDelete
  87. Hi Sam, I'm a little confused on how to access this from my viewmodel in WPF. If you could get back to me via email at reeceengle(at)gmail I would really appreciate it

    ReplyDelete
  88. Hi,

    When I bind the Property to my Player-object the Passwordfield is still null in my ViewModel, do you have any suggestions?Thanks in advance!

    ReplyDelete
  89. Thanks. You may want to change "d" to "box" in this line for the check to have the described effect:
    if (d == null || !GetBindPassword(d))

    ReplyDelete
  90. Hi, I just wonder you may have the above code in VB. As my project required me to built in VB and I 've problem to do the translation from C# to VB. Thanks

    ReplyDelete
  91. rooma roopchandani24 September 2012 at 08:11

    thanks..for the code

    ReplyDelete
  92. I'd suggest you try one of the many online C# to VB.Net converters, like
    http://converter.telerik.com/

    ReplyDelete
  93. You might want to try one of the many online C# to VB.Net converters, like
    http://converter.telerik.com/

    ReplyDelete
  94. Hi,
    That's really a very helpful piece of code.
    I suggest a small modification to HandlePasswordChanged handler to cope with navigation. The problem with your code is that PasswordBox clears the password on navigating to other pages, so that the password should only be update when the PasswordBox has the focus.

    private static void HandlePasswordChanged(object sender, RoutedEventArgs e) { PasswordBox box = sender as PasswordBox;
    if ((box != null) && box.IsFocused) { // set a flag to indicate that we're updating the password SetUpdatingPassword(box, true); // push the new password into the BoundPassword property SetBoundPassword(box, box.Password); SetUpdatingPassword(box, false); } }

    ReplyDelete
  95. Nice code.. work elegantly.

    ReplyDelete
  96. Awesome :)

    Thank you for this article . Works as needed !!

    ReplyDelete
  97. Awsome code. Passing on my thanks

    ReplyDelete
  98. how to access the password value in viewmodel

    ReplyDelete
  99. Wow, saved my day. thanks man. Brilliant work.

    ReplyDelete
  100. so many thanks, you saved my lots of time

    ReplyDelete
  101. greate article.thank you!!

    ReplyDelete
  102. look at this:http://seesharpdeveloper.blogspot.com/2013/03/binding-to-passwordbox-in-wpf-using-mvvm.html

    ReplyDelete