自定义密码文本框C#Windows应用程序

时间:2015-05-26 10:24:16

标签: c# winforms

我想在C#应用程序中实现自定义密码文本框。 默认情况下,.NET为我提供了这些属性。

 - PasswordChar
 - UseSystemPasswordChar

然而,上述选项对我不起作用,因为我想实现一个自定义密码文本框,这将允许我输入字母数字字符,但行为方式类似于Android文本框控件。即我必须显示输入的字符几毫秒,然后使用“ asterix ”或任何其他密码字符进行屏蔽。

为了实现这一点,我目前正以这种方式处理,但我认为这不是最佳解决方案。

private void txtPassword_TextChanged(object sender, EventArgs e)
    {

        if (timer == null)
        {
            timer = new System.Threading.Timer(timerCallback, null, 500, 150);
        }
        int num = this.txtPassword.Text.Count();
        if (num > 1)
        {
            StringBuilder s = new StringBuilder(this.txtPassword.Text);
            s[num - 2] = '*';
            this.txtPassword.Text = s.ToString();
            this.txtPassword.SelectionStart = num;
        }
    }

    public void Do(object state)
    {
        int num = this.txtPassword.Text.Count();
        if (num > 0)
        {
            StringBuilder s = new StringBuilder(this.txtPassword.Text);

            s[num - 1] = '*';
            this.Invoke(new Action(() =>
            {
                this.txtPassword.Text = s.ToString();
                this.txtPassword.SelectionStart = this.txtPassword.Text.Count();
                if (timer != null)
                {
                    timer.Dispose();
                }
                timer = null;
            }));
        }
    }

在构造函数中调用此代码段

timerCallback = new TimerCallback(Do);

非常确定这可以更轻松或更有效地完成。任何投入都受到高度赞赏。

由于 VATSAG

2 个答案:

答案 0 :(得分:3)

首先,除非您100%知道自己在做什么,否则实施自定义安全控制通常不是一个好主意。如果您使用的是WPF,那么您可以使用password reveal button密码盒控件来预览密码。

您现有的代码可以通过多种方式进行改进,最明显的是:

  1. 替换

    if(str.Length == 1)...

  2. ((TextBox)sender).Text=new string('*', str.Length);
    
    1. 使用Environment.NewLine而不是'\ n'。 (为什么你需要将它存储在密码数组中?)

    2. 在事件处理程序中使用boolean变量来禁用它的逻辑,而不是每次都附加\ detaching事件处理程序。

    3. 使用Timer而不是使用Thread.Sleep()

    4. 阻止UI线程

答案 1 :(得分:0)

试试这个。

在您输入下一个字符之前,第一个字符没有被更改,但是我会留给您调试:);)

我没有使用System.Threading.Timer,而是使用了Windows.Forms.Timer

更简单:)

public partial class Form1 : Form
{
    Timer timer = null;

    public Form1()
    {
        InitializeComponent();
        timer = new Timer();
        timer.Interval = 250;
        timer.Tick += Timer_Tick;
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        timer.Enabled = false;

        int num = this.txtPassword.Text.Count();
        if (num > 0)
        {
            StringBuilder s = new StringBuilder(this.txtPassword.Text);

            s[num - 1] = '*';
            this.Invoke(new Action(() =>
            {
                this.txtPassword.Text = s.ToString();
                this.txtPassword.SelectionStart = this.txtPassword.Text.Count();
            }));
        }
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        int num = this.txtPassword.Text.Count();
        if (num > 1)
        {
            StringBuilder s = new StringBuilder(this.txtPassword.Text);
            s[num - 2] = '*';
            this.txtPassword.Text = s.ToString();
            this.txtPassword.SelectionStart = num;
            timer.Enabled = true;
        }
    }
}