2011-11-03 18 views
20

入力を打つことなく入力した値を入力する前に、テキストボックスで入力を完了するまでC#で待機する方法はありますか?ユーザーがテキストボックスに1000年のような値を入力し、それ:私はここで2C#ユーザーがテキストボックスに入力を完了するのを待つ

によって乗算シンプルな電卓は、私はそれが何をしたいかである必要があり

オーケー:

はこの質問を少し改訂します自動的にここでは2000年

を表示する何が起こるかです:ユーザーが1個の、その2を乗算し、出力2

+14

「入力が完了しましたか」をどのように判断しますか?私は、C#が少なくとももう2つのバージョンのテレパシーイベントのハンドラを追加するとは思っていません。 – Donut

+1

ここでの問題は、「仕上げ」を定義することです。それは3秒、5などの入力を止めるときでしょうか?最も簡単な方法は、Enterのようなマーカーを使用するかボタンをクリックすることです。 – JaredPar

+0

あなたはしばらく待ってから、ユーザーが入力を終了した、またはtexboxにフォーカスがないと推測できますそれ以上のことはできません。 – evilone

答えて

2

テキストボックスonChange()イベントを使用できます。テキストボックスでテキストが変更された場合は、入力された値が数値であるかどうかをチェックし、他の値に応じて合計値を計算します。

+1

onChange()はVS2015 C#の下のテキストボックスのイベントではありません。 – Jhollman

+10

@Jhollman私は2011年にこの質問に答えました。それでは、Visual Studio 2015はありませんでした。 – evilone

+1

これはどのようにして質問に答えますか?さらに、なぜこれが選ばれた答えですか? – Krythic

4

あなたは毎回ユーザー仕上げを起動しますテキストボックスのLostFocusイベントを処理することができますに入るとすぐに入力するテキストボックスからナビゲートします。ここにはLostFocusのドキュメントがあります:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.lostfocus.aspx

しかし、「仕上げ」とはどういう意味なのかよくわからないので、ここでは正確に何をしようとしているのか分かりません。

0

タブやリターンのようなキーストロークに基づいてイベントをトリガーするとどうなりますか?

+0

タブやリターンがうまくいくと思います。これらのイベントを自分のコードに追加するには – user990951

+0

タブで 'LostFocus'イベントが発生します。http://msdn.microsoft.com/en-us/詳細については、/library/system.windows.forms.control.lostfocus.aspxを参照してください。 – esskar

+0

うん、lostfocusが最もよく動作し、それからイベントをトリガーする –

1

問題のテキストボックスに対してLeaveまたはLostFocusのいずれかのイベントを処理する必要があります。私は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

は別の簡単な解決策は、にタイマーを追加することですあなたフォーム、250にIntervalプロパティを設定し、次のようにタイマーの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ミリ秒後に更新されることを意味します。私が見ている限り、それはテキストボックスの入力を終了した後に更新を行います。 Btw。このプロパティは他のシナリオでも便利です(例: ListBoxなど

+0

入力中にソースを更新したい場合は、短い一時停止の後に、バインディングに 'UpdateSourceTrigger = PropertyChanged'も必要です。 – MgSam

3

私は同じ挑戦に直面しました。ここに私の簡単なアプローチがあります。これは問題なく動作します。 UWPで

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

、私は静的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 
     } 
    } 
関連する問題