C# wait for user to finish typing in a Text Box

前端 未结 15 1219
无人及你
无人及你 2020-11-27 18:16

Is there a way in C# to wait till the user finished typing in a textbox before taking in values they have typed without hitting enter?

Revised this question a little

相关标签:
15条回答
  • 2020-11-27 18:27

    Another simple solution would be to add a timer to your form, set the Interval property to 250 and then use the timer's tick event as follows:

    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();
    }
    
    0 讨论(0)
  • 2020-11-27 18:32

    I faced the same challenge, and here is my simple approach. This works without issues.

    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; 
                }
                    ));            
            }
        }
    
    0 讨论(0)
  • 2020-11-27 18:33

    I don't know if the onChange() only exists in an older version of c#, but I can't find it!

    The following works for detecting when a user either hits the Enter key, or tabs out of the TextBox, but only after changing some text:

        //--- 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  --- //
    
    0 讨论(0)
  • 2020-11-27 18:35

    Ideally an inheritance solution like esskar’s is the way to go but it doesn’t play well with the designer so to get the re-use I opted for a helper style side-class:

    using System;
    using System.Threading;
    using System.Windows.Forms;
    using Timer = System.Threading.Timer;
    
        internal class DelayedText : IDisposable
        {
            private readonly EventHandler _onTextChangedDelayed;
            private readonly TextBox _textBox;
            private readonly int _period;
            private Timer _timer;
    
            public DelayedText(TextBox textBox, EventHandler onTextChangedDelayed, int period = 250)
            {
                _textBox = textBox;
                _onTextChangedDelayed = onTextChangedDelayed;
                _textBox.TextChanged += TextBoxOnTextChanged;
                _period = period;
            }
    
            public void Dispose()
            {
                _timer?.Dispose();
                _timer = null;
            }
    
            private void TextBoxOnTextChanged(object sender, EventArgs e)
            {
                Dispose();
                _timer = new Timer(TimerElapsed, null, _period, Timeout.Infinite);
            }
    
            private void TimerElapsed(object state)
            {
                _onTextChangedDelayed(_textBox, EventArgs.Empty);
            }
        }
    

    Usage, in the form constructor:

    InitializeComponent();
    ...
    new DelayedText(txtEdit, txtEdit_OnTextChangedDelayed);
    

    I haven't kicked it hard, but seems to work for me.

    0 讨论(0)
  • 2020-11-27 18:39

    You want to use handle either the Leave or LostFocus event for the textbox in question. I'm assuming you are using WinForm even though you don't state it in your question.

    0 讨论(0)
  • 2020-11-27 18:39

    Most straight forward approach.

    *.xaml

    <TextBox Name="Textbox1"
                 TextChanged="Textbox1_TextChanged"/>
    

    *.xaml.cs

    using System.Threading.Tasks;
    
    public bool isChanging = false;
    async private void Textbox1_TextChanged(object sender,
                                            TextChangedEventArgs e)
        {
            // entry flag
            if (isChanging)
            {
                return;
            }
            isChanging = true;
            await Task.Delay(500);
    
            // do your stuff here or call a function
    
            // exit flag
            isChanging = false;
        }
    
    0 讨论(0)
提交回复
热议问题