How to show/hide password using passwordbox in wpf project

42 views Asked by At

I seen that passwordreveal method is not working for passwordbox in wpf, is there any way that I can show and hide password via checkbox?

I expect to show/ hide functionality exist in passwordbox in wpf

Or I just need to use text box to achieve this functionality

1

There are 1 answers

0
Emperor Eto On

PasswordBox doesn't have that functionality built in. The original design pre-dates when that option became popular on websites etc.

A simple solution is to build a UserControl that switches between a plain TextBox or PasswordBox.

EnhancedPasswordBox.xaml

<UserControl x:Class="SOExamples.EnhancedPasswordBox"
             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="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <PasswordBox x:Name="_hidden"
                     PasswordChanged="_hidden_PasswordChanged" />
        <TextBox x:Name="_visible"
                 Visibility="Collapsed"
                 TextChanged="_visible_TextChanged" />
        <CheckBox x:Name="_isVisible"
                  Grid.Row="1"
                  Click="_isVisible_Click"
                  Content="Show"
                  HorizontalAlignment="Right" />
    </Grid>
</UserControl>

EnhancedPasswordBox.xaml.cs

namespace SOExamples
{
    /// <summary>
    /// Interaction logic for EnhancedPasswordBox.xaml
    /// </summary>
    public partial class EnhancedPasswordBox : UserControl
    {
        public EnhancedPasswordBox()
        {
            InitializeComponent();
        }

        #region string Password dependency property
        public static DependencyProperty PasswordProperty = DependencyProperty.Register(
            "Password",
            typeof(string),
            typeof(EnhancedPasswordBox),
            new FrameworkPropertyMetadata(
                (string)null,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                (obj, args) =>
                {
                    ((EnhancedPasswordBox)obj).OnPasswordChanged(args);
                }));
        public string Password
        {
            get
            {
                return (string)GetValue(PasswordProperty);
            }
            set
            {
                SetValue(PasswordProperty, value);
            }
        }
        private void OnPasswordChanged(DependencyPropertyChangedEventArgs args)
        {
            if (_suspendChangeHandlers)
                return;
            _suspendChangeHandlers = true;
            this._visible.Text = args.NewValue as string;
            this._hidden.Password = args.NewValue as string;
            _suspendChangeHandlers = false;
        }

        #endregion

        private void _isVisible_Click(object sender, RoutedEventArgs e)
        {
            if (_isVisible.IsChecked == true)
            {
                this._hidden.Visibility = Visibility.Collapsed;
                this._visible.Visibility = Visibility.Visible;
            }
            else
            {
                this._hidden.Visibility = Visibility.Visible;
                this._visible.Visibility = Visibility.Collapsed;
            }
        }

        private void _hidden_PasswordChanged(object sender, RoutedEventArgs e)
        {
            if (_suspendChangeHandlers)
                return;
            _suspendChangeHandlers = true;
            this.SetCurrentValue(PasswordProperty, _hidden.Password);            
            this._visible.Text = _hidden.Password;
            _suspendChangeHandlers = false;
        }

        private void _visible_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (_suspendChangeHandlers)
                return;
            _suspendChangeHandlers = true;
            this.SetCurrentValue(PasswordProperty, _visible.Text);            
            this._hidden.Password = _visible.Text;
            _suspendChangeHandlers = false;
        }

        private bool _suspendChangeHandlers = false;
    }
}

Hidden:

Hidden

Visible:

Visible

Annoyingly PasswordBox doesn't let you bind to the password, but the UserControl exposes its own Password property to abstract that detail away.

A reader may wonder whether it would be better to use a SecureString here for the binding. You certainly could, but given the option to make the password visible, the plaintext string is going to exist in memory - probably in many places - no matter what, so you'd gain very little security (and a big amount of inconvenience) by doing so.