Click here to Skip to main content
15,885,365 members
Please Sign up or sign in to vote.
1.06/5 (4 votes)
See more:
Please tell me how to bind the PasswordBox with wpf in MVVM
Posted
Updated 26-Sep-18 3:56am

For security reason WPF didn't gave any Dependency property in Password box. How ever if you really want to achieve what you want then you can follow Samual Jack's[^] blog post where he gave an elegant solution.
 
Share this answer
 
The problem is that with PasswordBox there is no Idependency property :S
 
Share this answer
 
Comments
Abhinav S 14-Jan-11 9:19am    
Sorry, try this - http://www.wpftutorial.net/PasswordBox.html. You need to use an attached behaviour.
Use the below attached property to bind password box

C#
<pre>public class BoundPasswordBox
    {
        public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(BoundPasswordBox),
            new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));

        public static readonly DependencyProperty AttachProperty =DependencyProperty.RegisterAttached("Attach",typeof(bool), typeof(BoundPasswordBox), 
            new PropertyMetadata(false, Attach));

        private static readonly DependencyProperty IsUpdatingProperty =DependencyProperty.RegisterAttached("IsUpdating", typeof(bool),
           typeof(BoundPasswordBox));


        public static void SetAttach(DependencyObject dp, bool value)
        {
            dp.SetValue(AttachProperty, value);
        }

        public static bool GetAttach(DependencyObject dp)
        {
            return (bool)dp.GetValue(AttachProperty);
        }

        public static string GetPassword(DependencyObject dp)
        {
            return (string)dp.GetValue(PasswordProperty);
        }

        public static void SetPassword(DependencyObject dp, string value)
        {
            dp.SetValue(PasswordProperty, value);
        }

        private static bool GetIsUpdating(DependencyObject dp)
        {
            return (bool)dp.GetValue(IsUpdatingProperty);
        }

        private static void SetIsUpdating(DependencyObject dp, bool value)
        {
            dp.SetValue(IsUpdatingProperty, value);
        }

        private static void OnPasswordPropertyChanged(DependencyObject sender,DependencyPropertyChangedEventArgs e)
        {
            PasswordBox passwordBox = sender as PasswordBox;
            passwordBox.PasswordChanged -= PasswordChanged;

            if (!(bool)GetIsUpdating(passwordBox))
            {
                passwordBox.Password = (string)e.NewValue;
            }
            passwordBox.PasswordChanged += PasswordChanged;
        }

        private static void Attach(DependencyObject sender,DependencyPropertyChangedEventArgs e)
        {
            PasswordBox passwordBox = sender as PasswordBox;

            if (passwordBox == null)
                return;

            if ((bool)e.OldValue)
            {
                passwordBox.PasswordChanged -= PasswordChanged;
            }

            if ((bool)e.NewValue)
            {
                passwordBox.PasswordChanged += PasswordChanged;
            }
        }

        private static void PasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox passwordBox = sender as PasswordBox;
            SetIsUpdating(passwordBox, true);
            SetPassword(passwordBox, passwordBox.Password);
            SetIsUpdating(passwordBox, false);
        }

    }

Add the namespace of attached property ("here util:") and use like below:
<passwordbox x:name="TxtPassword" util:boundpasswordbox.attach="True" util:boundpasswordbox.password="{Binding Path=Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True,NotifyOnValidationError=True}" xmlns:util="#unknown" xmlns:x="#unknown">
</passwordbox>
 
Share this answer
 
In your View:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

....

XML
<PasswordBox Grid.Column="1" PasswordChar="*" x:Name="pwbox"     Password="test"   >
                      <i:Interaction.Triggers>
                          <i:EventTrigger EventName="PasswordChanged" >
                              <i:InvokeCommandAction Command="{Binding PasswordChangedCommand }"  CommandParameter="{Binding ElementName=pwbox,  Mode=OneWay}"/>
                          </i:EventTrigger>
                      </i:Interaction.Triggers>
                  </PasswordBox>





In the ViewModel(wich is DataContext of your View):

C#
public ICommand PasswordChangedCommand
    {
        get
        {
            return new RelayCommand<object>(ExecChangePassword);
        }
    }

  

    private void ExecChangePassword(object obj)
    {
        yourPassword = ((System.Windows.Controls.PasswordBox)obj).Password;
    }



Some other class...
XML
public class RelayCommand<T> : ICommand
{

 
 
    /// <param name="execute">The execution logic.</param>
    public RelayCommand(Action<T> execute)
        : this(execute, null)
    {
    }
      public void Execute(Object parameter)
        {
            _execute((T)parameter);
        }}
 
Share this answer
 
v2
I spent ages trying to get this working. In the end, I gave up and just used the DevExpress PasswordBoxEdit. It allows binding.

https://www.devexpress.com/Support/Center/Question/Details/Q506351[^]
 
Share this answer
 
v2
You could start with this[^] article.
 
Share this answer
 
Why not Pass the whole Password object to ViewModel.I believe there is also a login or submit button. pass the passwordbox object via the submit button(as commandparameter).
C#
<passwordbox name="password" />
<button>
<interactivity:interaction.triggers xmlns:interactivity="#unknown">
<interactivity:eventtrigger eventname="Click">
<cmd:eventtocommand command="{Binding SignIn}" commandparameter="{Binding ElementName=password}" xmlns:cmd="#unknown" />
</interactivity:eventtrigger>
</interactivity:interaction.triggers>
</button>
/*
xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
*/


Then cast it to Passwordbox object in ViewModel
C#
private void SigningIn(object parameter)
{
PasswordBox PasswordObj= parameter as PasswordBox;
string Password = password.Password;//here is the entered password
}
 
Share this answer
 
v2
 
Share this answer
 
Comments
CHill60 25-May-17 6:57am    
The question is over 6 years old and already resolved.
pitambar sahoo 4-Jun-17 1:55am    
Can you please share the link , where I can get the answer.
CHill60 4-Jun-17 8:40am    
There are several links posted in the solutions above! Someone using an appropriate search should find the MS document you refer to sooner than any of the solutions here.
If you need to find the answer why did you post a solution? (That is rhetorical by the way)
<PasswordBox x:Name="txtPassword" Margin="0,10" materialDesign:HintAssist.Hint="Password" Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" FontFamily="Champagne & Limousines" FontSize="18" PasswordChanged="txtPassword_PasswordChanged">
                        <PasswordBox.DataContext>
                            <Binding Path="Password" UpdateSourceTrigger="PropertyChanged">
                                <Binding.ValidationRules>
                                    <demo:NotEmptyValidationRule ValidatesOnTargetUpdated="True" />
                                </Binding.ValidationRules>
                            </Binding>
                        </PasswordBox.DataContext>
                    </PasswordBox>


cs code:

private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e)
       {

           loginViewModel.Password = txtPassword.Password;
           loginViewModel.UserName = txtUserName.Text;
           DataContext = loginViewModel;
       }



Call Class File:
public class LoginViewModel : INotifyPropertyChanged
  {
      private string _UserName;
      private string _Password;
      public LoginViewModel()
      {
          LongListToTestComboVirtualization = new List<int>(Enumerable.Range(0, 1000));
      }
      public string UserName
      {
          get { return _UserName; }
          set
          {
              this.MutateVerbose(ref _UserName, value, RaisePropertyChanged());
          }
      }
      public string Password
      {
          get { return _Password; }
          set
          {
              this.MutateVerbose(ref _Password, value, RaisePropertyChanged());
          }
      }

      public IList<int> LongListToTestComboVirtualization { get; }

      public DemoItem DemoItem => new DemoItem("Mr. Test", null, Enumerable.Empty<DocumentationLink>());

      public event PropertyChangedEventHandler PropertyChanged;

      private Action<PropertyChangedEventArgs> RaisePropertyChanged()
      {
          return args => PropertyChanged?.Invoke(this, args);
      }
  }




For Validation Class:

public class NotEmptyValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            return string.IsNullOrWhiteSpace((value ?? "").ToString())
                ? new ValidationResult(false, "Field is required.")
                : ValidationResult.ValidResult;
            
        }
    }
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900