简体   繁体   中英

Custom Password textbox C# Windows Application

I want to implement a custom password textbox in C# application. .NET by default provides me with these properties.

 - PasswordChar
 - UseSystemPasswordChar

However the above options wont work for me as I want to implement a custom password textbox which will allow me to enter alphanumeric characters but behaves in a way similar to Android textbox controls. ie I have to display the character entered for a few milliseconds before masking it using " asterix " or any other password character.

To implement this, I'm handling this way currently but I think it's not the optimal solution.

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;
            }));
        }
    }

With this snippet called in the Constructor

timerCallback = new TimerCallback(Do);

Pretty much sure this can be done more easily or efficiently. Any inputs highly appreciated.

Thanks VATSAG

First of all, it's generally not a good idea to implement custom security controls, unless you 100% know what are you doing. If you were using WPF, you could have nice and convinient way to preview the password with password reveal button of PasswordBox control.

Your existing code can be improved in many ways, most obvious are:

  1. Replace

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

with

((TextBox)sender).Text=new string('*', str.Length);
  1. Use Environment.NewLine instead of '\\n'. (Why you need to store it in password array at all?)

  2. Use boolean variable inside event handler to disable it's logic instead of attaching\\detaching event handler every time.

  3. Use Timer instead of blocking UI thread with Thread.Sleep()

Try this.

There was an issue with the very first character that didn't get changed before you typed in the next one, but i will leave that to you for debugging :) ;)

Instead of using the System.Threading.Timer, i used the Windows.Forms.Timer

Much simpler :)

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;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM