2011-11-03 61 views
20

C#中有没有一种方法可以等待用户在输入未输入的值之前输入文本框?C#等待用户在文本框中输入完成

修正这个问题有点:

好吧,我有一个简单的计算器,通过2

这里相乘就是我想要它做的事:用户输入,比如1000的值到一个文本框,它自动显示2000年

这里是发生了什么:只要用户在1其乘以2,输出2

+14

如何确定他们“已完成打字?”我不认为C#会为至少另外几个版本的心灵感应事件添加处理程序... – Donut

+1

这里的问题是您必须定义“完成”。是否当他们停止键入3秒,5等...最简单的方法是使用一个标记,如回车或点击一个按钮 – JaredPar

+0

你可以等待一段时间,只是猜测用户已经结束键入或texbox没有焦点再也...否则你不能 – evilone

回答

2

您可以使用文本框onChange()事件。如果文本在文本框中发生更改,请检查输入的值是否是数字,并根据其他值计算总值。

+1

onChange()不是VS2015 c#下的文本框事件。 – Jhollman

+10

@Jhollman我在2011年回答了这个问题。那么,那么就没有Visual Studio 2015. – evilone

+1

这是怎么回事?此外,为什么这是选择的答案? – Krythic

0

如果您基于类似标签或返回的按键触发事件,该怎么办?

+0

我猜标签或返回将工作如何将这些类型的事件添加到我的代码 – user990951

+0

选项卡将导致'LostFocus'事件,请参阅http://msdn.microsoft.com/en-us /library/system.windows.forms.control.lostfocus.aspx了解更多详情。 – esskar

+0

是的,lostfocus会最好,然后触发你的事件 –

1

您想要为相关文本框使用句柄LeaveLostFocus事件。我假设你使用WinForm,即使你没有在你的问题中说明它。

39

现在我将“完成键入”定义为“用户键入了某些内容,但在某个时间后没有键入任何内容”。把它作为一个定义,我写了一个从TextBox派生出来的小类,将它扩展为DelayedTextChanged事件。我不确定它是否完整且无错误,但是它满足了一个小小的烟雾测试。随意更改和/或使用它。我把它叫做MyTextBox因为我现在无法想出一个更好的名字。您可以使用DelayedTextChangedTimeout属性更改等待超时。默认值是10000ms(= 10秒)。

public class MyTextBox : TextBox 
{ 
    private Timer m_delayedTextChangedTimer; 

    public event EventHandler DelayedTextChanged; 

    public MyTextBox() : base() 
    { 
     this.DelayedTextChangedTimeout = 10 * 1000; // 10 seconds 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (m_delayedTextChangedTimer != null) 
     { 
      m_delayedTextChangedTimer.Stop(); 
      if (disposing) 
       m_delayedTextChangedTimer.Dispose(); 
     } 

     base.Dispose(disposing);    
    } 

    public int DelayedTextChangedTimeout { get; set; } 

    protected virtual void OnDelayedTextChanged(EventArgs e) 
    { 
     if (this.DelayedTextChanged != null) 
      this.DelayedTextChanged(this, e); 
    } 

    protected override void OnTextChanged(EventArgs e) 
    { 
     this.InitializeDelayedTextChangedEvent(); 
     base.OnTextChanged(e);    
    }     

    private void InitializeDelayedTextChangedEvent() 
    { 
     if (m_delayedTextChangedTimer != null) 
      m_delayedTextChangedTimer.Stop(); 

     if (m_delayedTextChangedTimer == null || m_delayedTextChangedTimer.Interval != this.DelayedTextChangedTimeout) 
     {     
      m_delayedTextChangedTimer = new Timer(); 
      m_delayedTextChangedTimer.Tick += new EventHandler(HandleDelayedTextChangedTimerTick); 
      m_delayedTextChangedTimer.Interval = this.DelayedTextChangedTimeout; 
     } 

     m_delayedTextChangedTimer.Start(); 
    } 

    private void HandleDelayedTextChangedTimerTick(object sender, EventArgs e) 
    { 
     Timer timer = sender as Timer; 
     timer.Stop(); 

     this.OnDelayedTextChanged(EventArgs.Empty); 
    } 
} 
1

我不知道onChange()是否只存在于旧版本的c#中,但我找不到它!

检测下工作时,用户无论点击回车键或切换到该文本框的,但改变一些文字后才:

//--- this block deals with user editing the textBoxInputFile --- // 
    private Boolean textChanged = false; 
    private void textBoxInputFile_TextChanged(object sender, EventArgs e) { 
     textChanged = true; 
    } 
    private void textBoxInputFile_Leave(object sender, EventArgs e) { 
     if (textChanged) { 
      fileNameChanged(); 
     } 
     textChanged = false; 
    } 
    private void textBoxInputFile_KeyDown(object sender, KeyEventArgs e) { 
     if (textChanged & e.KeyCode == Keys.Enter) { 
      fileNameChanged(); 
     } 
     textChanged = false; 
    } 
    //--- end block --- // 
12

另一种简单的解决方案是将一个计时器添加到您的形式,Interval属性设置为250,然后使用计时器的Tick事件如下:

private void timer1_Tick(object sender, EventArgs e) 
{ 
    timer1.Stop(); 
    Calculate(); // method to calculate value 
} 

private void txtNumber_TextChanged(object sender, EventArgs e) 
{ 
    timer1.Stop(); 
    timer1.Start(); 
} 
6

如果您正在使用WPF和.NET 4.5或更高版本上有一个名为控制的结合部的新属性“延迟”。它定义了源更新后的时间范围。

<TextBox Text="{Binding Name, Delay=500}" /> 

这意味着源仅在500毫秒后更新。据我所知,它在TextBox输入后更新结束。顺便说一句。这个属性也可以在其他场景中有用,例如。列表框等

+0

如果您希望在输入时更新源代码,短暂停顿后,还需要绑定中的“UpdateSourceTrigger = PropertyChanged”。 – MgSam

3

我面临同样的挑战,这里是我的简单方法。这工作没有问题。

public partial class Form2 : Form 
    { 
     static int VALIDATION_DELAY = 1500; 
     System.Threading.Timer timer = null; 
     public Form2() 
     { 
      InitializeComponent(); 
     } 

     private void textBox1_TextChanged(object sender, EventArgs e) 
     { 
      TextBox origin = sender as TextBox; 
      if (!origin.ContainsFocus) 
       return; 

      DisposeTimer(); 
      timer = new System.Threading.Timer(TimerElapsed, null, VALIDATION_DELAY, VALIDATION_DELAY); 

     } 
     private void TimerElapsed(Object obj) 
     { 
      CheckSyntaxAndReport(); 
      DisposeTimer();    
     } 

     private void DisposeTimer() 
     { 
      if (timer != null) 
      { 
       timer.Dispose(); 
       timer = null; 
      } 
     } 

     private void CheckSyntaxAndReport() 
     {    
      this.Invoke(new Action(() => 
      { 
       string s = textBox1.Text.ToUpper(); //Do everything on the UI thread itself 
       label1.Text = s; 
      } 
       ));    
     } 
    } 
1

在UWP,我通过使静态lastTimeOfTyping和检查的时间当“框TextChanged”事件发生做了延迟检查。当新的“TextChanged”时间匹配并等待,直到静态lastTimeOfTyping匹配,然后执行所需的功能。

private const int millisecondsToWait = 500; 
    private static DateTime s_lastTimeOfTyping; 
    private void SearchField_OnTextChanged(object sender, TextChangedEventArgs e) 
    { 
     var latestTimeOfTyping = DateTime.Now; 
     var text = ((TextBox)sender).Text; 
     Task.Run(()=>DelayedCheck(latestTimeOfTyping, text)); 
     s_lastTimeOfTyping = latestTimeOfTyping; 
    } 

    private async Task DelayedCheck(DateTime latestTimeOfTyping, string text) 
    { 
     await Task.Delay(millisecondsToWait); 
     if (latestTimeOfTyping.Equals(s_lastTimeOfTyping)) 
     { 
      // Execute your function here after last text change 
      // Will need to bring back to the UI if doing UI changes 
     } 
    }