Bindable passwordBox in WPF

Bindable PasswordBox in WPF MVVM using DependencyProperty and UserControl

One of WPF's most common pain points is that the PasswordBox control's Password property is not a DependencyProperty — meaning you can't data-bind it in XAML the usual way. This is by design for security reasons, but it creates friction when working with MVVM.

The cleanest solution is to wrap PasswordBox in a custom UserControl that exposes a proper bindable dependency property.

Why PasswordBox.Password Isn't Bindable

Microsoft intentionally made Password a regular CLR property (not a DependencyProperty) to prevent the password value from lingering in memory through the WPF property system, reducing the attack surface for memory inspection. This means you cannot use {Binding} on it directly.

The XAML — BindablePasswordBox UserControl

<UserControl x:Class="YourApp.Components.BindablePasswordBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                                                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                                                                 mc:Ignorable="d"
                                                                              d:DesignHeight="30" d:DesignWidth="200">
                                                                                  <PasswordBox x:Name="passwordBox" PasswordChanged="PasswordBox_PasswordChanged" />
                                                                                  </UserControl>

The Code-Behind — C# Implementation

public partial class BindablePasswordBox : UserControl
{
    private bool _isPasswordChanging = false;
    
        public string Password
            {
                    get { return (string)GetValue(PasswordProperty); }
                            set { SetValue(PasswordProperty, value); }
                                }
                                
                                    public static readonly DependencyProperty PasswordProperty =
                                            DependencyProperty.Register(
                                                        "Password",
                                                                    typeof(string),
                                                                                typeof(BindablePasswordBox),
                                                                                            new FrameworkPropertyMetadata(
                                                                                                            string.Empty,
                                                                                                                            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                                                                                                                            PasswordPropertyChanged,
                                                                                                                                                            null,
                                                                                                                                                                            false,
                                                                                                                                                                                            UpdateSourceTrigger.PropertyChanged));
                                                                                                                                                                                            
                                                                                                                                                                                                private static void PasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
                                                                                                                                                                                                    {
                                                                                                                                                                                                            if (d is BindablePasswordBox passwordBox)
                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                passwordBox.UpdatePassword();
                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                private void UpdatePassword()
                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                            if (!_isPasswordChanging)
                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                passwordBox.Password = Password;
                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                            }
                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
                                                                                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                                                                                            _isPasswordChanging = true;
                                                                                                                                                                                                                                                                                                                    Password = passwordBox.Password;
                                                                                                                                                                                                                                                                                                                            _isPasswordChanging = false;
                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                }

Usage in XAML (MVVM Binding)

Once the control is created, you can use it just like any other bindable control:

<local:BindablePasswordBox Password="{Binding UserPassword, Mode=TwoWay}" />

ViewModel

public class LoginViewModel : INotifyPropertyChanged
{
    private string _userPassword;
        public string UserPassword
            {
                    get => _userPassword;
                            set { _userPassword = value; OnPropertyChanged(); }
                                }
                                
                                    public ICommand LoginCommand => new RelayCommand(_ => DoLogin());
                                    
                                        private void DoLogin()
                                            {
                                                    // Use _userPassword here
                                                        }
                                                        }

Summary

The BindablePasswordBox pattern is the standard MVVM-friendly approach to password binding in WPF. The _isPasswordChanging flag prevents infinite loops when the property is updated from both directions. This pattern is clean, reusable, and fully compatible with data binding and commands.

Post a Comment

Previous Post Next Post