使用" smart"创建一个文本框密码字符

时间:2013-12-19 12:27:58

标签: c# multithreading textbox compact-framework

我正在使用.NET 3.5 CF并尝试创建一个文本框,该文本框应该隐藏写在其中的字符。这可以通过将参数PasswordChar设置为=“*”来实现。但是,这会直接将char更改为*。

我想要的是一个“智能”文本框,它会在延迟(大约1秒)后将字符更改为*,这将使用户获得一些正确写入字符的反馈。

我通过创建另一个应该处理这个问题的线程来尝试这个,因为用户仍然可以写更多的字符而不是等待这个延迟。我做了这样的事情:

                if (UseModernPasswordScreenMaskning)
                {
                    this.Invoke(new UpdateTextCallback(this.UpdateText), new object[]{"*"});
                }

     private void UpdateText(string text)
    {
        int k = this.Text.Length;
        System.Threading.Thread.Sleep(1000);
        this.Text = this.Text.Remove(k - 1, 1);
        this.Text = this.Text.Insert(k - 1, "*");
    }

它可以工作,但睡眠在我当前的线程上,使得下一个字母在出现之前写入延迟1秒。我想让每个字母直接显示并在写完特定字符后1秒钟更改为*。

2 个答案:

答案 0 :(得分:1)

据我了解,“智能”密码文本框是

  1. 最后一个字符将变为*在1s内
  2. 如果用户键入新字符,则旧字符将变为*(尽管它不会持续1秒)
  3. 所以

    1. 创建一个定时器回调,间隔为1秒,将最后一个字符更改为*

    2. 在smartTextBox_TextChanged事件中,将前一个字符更改为*

    3. 这是我的代码

      public void Do(object state)
          {
              int num = this.textBox1.Text.Count();
              if (num > 0)
              {
                  StringBuilder s = new StringBuilder(this.textBox1.Text);
      
                  s[num - 1] = '*';
                  this.Invoke(new Action(() =>
                  {
                      this.textBox1.Text = s.ToString();
                      this.textBox1.SelectionStart = this.textBox1.Text.Count();
                      timer.Dispose();
                      timer = null;
                  }));
              }
          }
      
          private void textBox1_TextChanged(object sender, EventArgs e)
          {
              if (timer == null)
              {
                  timer = new System.Threading.Timer(timerCallback, null, 1000, 1000);
              }
              int num = this.textBox1.Text.Count();
              if (num > 1)
              {
                  StringBuilder s = new StringBuilder(this.textBox1.Text);
                  s[num - 2] = '*';
                  this.textBox1.Text = s.ToString();
                  this.textBox1.SelectionStart = num;                   
              }
          }
      

      初始化

      timerCallback = new TimerCallback(Do);
      

答案 1 :(得分:0)

我设法通过添加行“int num = this.textBox1.Text.Count();”来解决它。在该声明之前无法使用:

    public void Do(object state)
    {
        if (this.logonPwTxtBox.InvokeRequired)
        { .. }
     }