使用文本框作为密码框,在wpf中设置密码字符

时间:2014-09-14 11:17:28

标签: c# wpf xaml

我在尝试使用密码char和占位符设置文本框时遇到问题。我已经为用户名完成了一个用户名,但工作正常,但是我对使用密码箱可以做些什么感到难过。

我知道您可以使用密码为char的密码框但是在wpf中也没有占位符。

我有这个用户名,我想为密码箱做同样的事情:

this.usernameTxt.Foreground = Brushes.LightGray;

        this.usernameTxt.Text = "Username";

this.usernameTxt.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(this.usernameTxt_Selected);

this.usernameTxt.PreviewLostKeyboardFocus += new KeyboardFocusChangedEventHandler(this.usernameTxt_Lostfocus);

public void usernameTxt_Lostfocus(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(usernameTxt.Text))
                    {
                        this.usernameTxt.Text = "Username";
                        this.usernameTxt.Foreground = Brushes.LightGray;
                    }
    }

    public void usernameTxt_Selected(object sender, EventArgs e)
    {
            this.usernameTxt.Focus();
            this.usernameTxt.SelectAll();
            this.usernameTxt.Text = "";
            this.usernameTxt.Foreground = Brushes.Black;
    }

1 个答案:

答案 0 :(得分:2)

这是您可以查看的解决方法。 在这个例子中,我依赖于我的文本框控件的TextChanged事件,它嵌入在密码控件中。

当触发TextChanged事件时,我使用堆栈捕获输入的最后一个字符,然后在视图模型中维护一个混淆密码和一个实际密码。 当按下删除键或后退键时,我弹出从堆栈输入的最后一个字符。

<强> XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:converters="clr-namespace:WpfApplication1.Converters"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <PasswordBox x:Name="passwordBox" Height="20" PasswordChar="*" Width="200" Background="LightYellow" >
            <PasswordBox.Template>
                <ControlTemplate>
                    <TextBox x:Name="PasswordTextbox" GotFocus="GotFocus" Text="{Binding ObfuscatedPassword, Mode=TwoWay}" KeyUp="PasswordTextbox_KeyUp" TextAlignment="Center" Foreground="LightGray" />
                </ControlTemplate>
            </PasswordBox.Template>
        </PasswordBox>
    </Grid>
</Window>

查看模型:

namespace WpfApplication1
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string obfuscatedPassword = "user name";

        public string ObfuscatedPassword
        {
            get { return obfuscatedPassword; }
            set 
            { 
                if (this.obfuscatedPassword != value)
                {
                    this.obfuscatedPassword = value;
                    OnPropertyChanged();
                }
            }
        }

        private string actualPassword = null;
        public string ActualPassword
        {
            get { return actualPassword; }
            set
            {
                if (this.actualPassword != value)
                {
                    this.actualPassword = value;
                    OnPropertyChanged();
                }
            }
        }

        private void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

<强>代码隐藏:

public partial class MainWindow : Window
{
    ViewModel viewModel = null;
    public MainWindow()
    {
        InitializeComponent();

        this.viewModel = this.DataContext as ViewModel;
    }

    public string defaultText = "user name";

    Stack<string> charStack = new Stack<string>();


    private void PasswordTextbox_KeyUp(object sender, KeyEventArgs e)
    {
        var textbox = sender as TextBox;
        textbox.Text = string.Empty;

        var key = e.Key.ToString();

        if (this.viewModel.ObfuscatedPassword == defaultText)
        {
            this.viewModel.ObfuscatedPassword = string.Empty;
        }

        var deleteLastCharacter = (e.Key == Key.Delete || e.Key == Key.Back);

        if (deleteLastCharacter)
        {

            if (charStack.Count > 0)
            {
                charStack.Pop();
            }

            if (charStack.Count == 0)
            {
                textbox.Text = defaultText;
                textbox.CaretIndex = defaultText.Length;
                textbox.SelectAll();
                e.Handled = true;
                return;
            }
        }
        else if (IsTextAllowed(key))
        {
            charStack.Push(key);
        }
        else
        {
            e.Handled = true;
            return;
        }

        this.viewModel.ObfuscatedPassword = ObfuscatePassword();
        this.viewModel.ActualPassword = ActualizePassword();

        textbox.CaretIndex = this.viewModel.ObfuscatedPassword.Length;
        e.Handled = true;
    }

    private static bool IsTextAllowed(string text)
    {
        Regex regex = new Regex(@"^.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$"); //regex that matches disallowed text
        return !regex.IsMatch(text);
    }

    private string ActualizePassword()
    {
        var password = string.Empty;

        foreach (var character in charStack.Reverse())
        {
            password += character;
        }

        return password;
    }

    private string ObfuscatePassword()
    {
        var password = string.Empty;

        foreach (var character in charStack.Reverse())
        {
            password += passwordBox.PasswordChar;
        }

        return password;
    }

    private void GotFocus(object sender, RoutedEventArgs e)
    {
        if (this.viewModel.ObfuscatedPassword == defaultText)
        {
            this.viewModel.ObfuscatedPassword = string.Empty;
        }
    }

}