Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
WPF - Bindable PasswordBox
using System.Windows;
using System.Windows.Controls;
namespace CustomControl
{
public class BindablePasswordBox : Decorator
{
/// <summary>
/// The password dependency property.
/// </summary>
public static readonly DependencyProperty PasswordProperty;
private bool isPreventCallback;
private RoutedEventHandler savedCallback;
/// <summary>
/// Static constructor to initialize the dependency properties.
/// </summary>
static BindablePasswordBox()
{
PasswordProperty = DependencyProperty.Register(
"Password",
typeof(string),
typeof(BindablePasswordBox),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnPasswordPropertyChanged))
);
}
/// <summary>
/// Saves the password changed callback and sets the child element to the password box.
/// </summary>
public BindablePasswordBox()
{
savedCallback = HandlePasswordChanged;
PasswordBox passwordBox = new PasswordBox();
passwordBox.PasswordChanged += savedCallback;
Child = passwordBox;
}
/// <summary>
/// The password dependency property.
/// </summary>
public string Password
{
get { return GetValue(PasswordProperty) as string; }
set { SetValue(PasswordProperty, value); }
}
/// <summary>
/// Handles changes to the password dependency property.
/// </summary>
/// <param name="d">the dependency object</param>
/// <param name="eventArgs">the event args</param>
private static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs eventArgs)
{
BindablePasswordBox bindablePasswordBox = (BindablePasswordBox) d;
PasswordBox passwordBox = (PasswordBox) bindablePasswordBox.Child;
if (bindablePasswordBox.isPreventCallback)
{
return;
}
passwordBox.PasswordChanged -= bindablePasswordBox.savedCallback;
passwordBox.Password = (eventArgs.NewValue != null) ? eventArgs.NewValue.ToString() : "";
passwordBox.PasswordChanged += bindablePasswordBox.savedCallback;
}
/// <summary>
/// Handles the password changed event.
/// </summary>
/// <param name="sender">the sender</param>
/// <param name="eventArgs">the event args</param>
private void HandlePasswordChanged(object sender, RoutedEventArgs eventArgs)
{
PasswordBox passwordBox = (PasswordBox) sender;
isPreventCallback = true;
Password = passwordBox.Password;
isPreventCallback = false;
}
}
}
Owner

taylorleese commented Jul 8, 2010

This is a workaround for the fact that the Password property of System.Windows.Controls.PasswordBox is not a DependencyProperty. This creates a new BindablePasswordBox using System.Windows.Controls.Decorator.

Palatis commented Aug 17, 2013

How do I expose the "Padding" property of the underlying PasswordBox?

I tried to add a new DependencyProperty "PaddingProperty":

public static readonly DependencyProperty PaddingProperty = DependencyProperty.Register(
    "Padding", typeof(double), typeof(BindablePasswordBox),
    new FrameworkPropertyMetadata(new Thickness(2), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnPaddingPropertyChanged))
);

public Thickness Padding
{
    get { return (Thickness)GetValue(PaddingProperty); }
    set { SetValue(PaddingProperty, value); }
}

but I cannot set it in XAML, says something about type mismatch.

Is there an attribute I can add to the Padding property so WPF will accept my values in xaml?

example xaml:

                <UniformGrid>
                    <Label VerticalAlignment="Center" HorizontalAlignment="Right">Password</Label>
                    <PasswordBox Height="20" Width="70" HorizontalAlignment="Left"></PasswordBox>
                </UniformGrid>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment