2013-12-19 5 views
1

Я использую .NET 3.5 CF и пытаюсь создать текстовое поле, которое должно скрывать написанный внутри него символ. Это работает, установив параметр PasswordChar равным «*». Однако это изменит char на a * напрямую.Создайте текстовое поле с «умным» паролем 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 секунду после написания определенного символа.

ответ

1

Как я понимаю, «умный» пароль текстовое поле является

  1. последний символ будет * в течение 1 сек
  2. если пользователь введите новый символ, старший один будет * (хотя это Безразлично» т последние 1s)

Так

  1. Создание обратного вызова таймера с интервалом 1с изменить последний символ *

  2. В smartTextBox_TextChanged случае, измените предыдущий символ *

Вот мой код

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); 
+0

Спасибо !, однако, когда вы делаете, как будто вы предложили мне получить сообщение об ошибке, когда код находится внутри функции «Do». «Control.Invoke» должен использоваться для взаимодействия с элементами управления, созданными в отдельном потоке ». Это я хочу, чтобы я это сделал, но не знаю, как это сделать. Текстовое поле создается в том же потоке, который является проблемой. – HappySoftwareDeveloper

+0

i снова запустите этот код и не увидите никаких проблем, это странно – Gintama

+0

Рад слышать, что вы решили эту ошибку! – Gintama

0

мне удалось для его решения путем добавления с строки «int num = this.textBox1.Text.Count();» не использовались до этого утверждения:

public void Do(object state) 
    { 
     if (this.logonPwTxtBox.InvokeRequired) 
     { .. } 
    } 
Смежные вопросы