Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Binding Passwords

0.00/5 (No votes)
29 Jun 2009 1  
Binding passwords

Those who've been following my blog and conversations with the WPF Disciples know that I love the databinding power of WPF, and in almost all cases, I'm a very happy bunny. There is one stain in the awe inspiring goodness that is bound applications, and that’s the PasswordBox. Superficially, this control looks like a textbox, but there is a problem when you write MVVM applications and rely on binding the way I do; you can't bind to it. Yes, you heard it right, you can't bind with a PasswordBox.

There’s a good reason for this lack of binding – PasswordBox.Password is not a Dependency Property, ostensibly because this would result in the password being stored in clear text in memory, which is a potential security concern. If, however, you aren't too worried about this potential security breach, there is a workaround. Good news, folks – the following class (taken from my forthcoming Twitter client Songbird) is a way to perform binding with the PasswordBox.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace SongBird.Infrastructure
{
    /// <summary>
    /// This class adds binding capabilities to the standard WPF PasswordBox.
    /// </summary>
    public class BoundPasswordBox
    {
        #region BoundPassword
        private static bool _updating = false;

        /// <summary>
        /// BoundPassword Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty BoundPasswordProperty =
            DependencyProperty.RegisterAttached("BoundPassword",
                typeof(string),
                typeof(BoundPasswordBox),
                new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged));

        /// <summary>
        /// Gets the BoundPassword property.
        /// </summary>
        public static string GetBoundPassword(DependencyObject d)
        {
            return (string)d.GetValue(BoundPasswordProperty);
        }

        /// <summary>
        /// Sets the BoundPassword property.
        /// </summary>
        public static void SetBoundPassword(DependencyObject d, string value)
        {
            d.SetValue(BoundPasswordProperty, value);
        }

        /// <summary>
        /// Handles changes to the BoundPassword property.
        /// </summary>
        private static void OnBoundPasswordChanged(
            DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            PasswordBox password = d as PasswordBox;
            if (password != null)
            {
                // Disconnect the handler while we're updating.
                password.PasswordChanged -= PasswordChanged;
            }

            if (e.NewValue != null)
            {
                if (!_updating)
                {
                    password.Password = e.NewValue.ToString();
                }
            }
            else
            {
                password.Password = string.Empty;
            }
            // Now, reconnect the handler.
            password.PasswordChanged += new RoutedEventHandler(PasswordChanged);
        }

        /// <summary>
        /// Handles the password change event.
        /// </summary>
        static void PasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox password = sender as PasswordBox;
            _updating = true;
            SetBoundPassword(password, password.Password);
            _updating = false;
        }

        #endregion
    }
}

Using it couldn't be simpler, just add a reference to the namespace in your XAML, and update your PasswordBox with the BoundPasswordBox class. You've now got a bindable PasswordBox.

<PasswordBox

    Grid.Column="1"

    Grid.Row="2"

    Margin="5,5,5,5"

    password:BoundPasswordBox.BoundPassword="{Binding Path=Password,
        Mode=TwoWay,
        UpdateSourceTrigger=PropertyChanged}"

    VerticalAlignment="Center"/>

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here