普通TextBox中的自动文本修正

时间:2011-11-23 08:37:27

标签: c# winforms string events autocorrect

我想在我的应用程序中的某些TextBox es中实现自动更正。我的意思是当用户输入文本时,几秒钟后,文本应该传递给方法,得到纠正并传回文本框。

目前我有一个非常基本的纠正程序。我的TextBoxes应该从用户那里获得一个测量值(例如1.25 mA1.25uA.666 A)。

想象一下,我有一个名为CorrectValue的修正方法:

private void CorrectValue(TextBox tb)
{
   tb.Text = tb.Text.Trim().Remove('', string.Empty);
   //Actual correction is going to be much more complicated
}

那么这样做最好的方法是什么?应该举起什么样的活动?如何计算用户在TextBox中写入的秒数?

5 个答案:

答案 0 :(得分:2)

验证输入的最佳位置是TextBox控件的事件Validating。如果输入的值无效,请将该事件中的e.Cancel设置为false。

答案 1 :(得分:2)

对我来说,此类更正/输入验证的最佳事件是Validating事件。

TextChanged问题是,它在键入时发生,您无法确定用户是否已完成输入。

答案 2 :(得分:1)

最基本的实现是您使用Textbox的TextChanged事件。在这种情况下,您可以使用方法CorrectValue()。作为函数的参数,您可以将事件的'sender'参数强制转换为TextBox并将其传递给您的方法。

修改 为了计算时间,你可以设置一个定时器,例如每0.5秒触发一次。之后,比方说,你调用Correction方法2秒。例如:

private int _ticks;

private void textBox1_TextChanged(object sender, EventArgs e)
{
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    if (_ticks++ == 4)
    {
        //Call correction method
        timer1.Stop();
        _ticks = 0;
    }
}

答案 3 :(得分:1)

这是我所做的 silverlight 用户控件(它是实际生产代码的摘录,完美无缺地工作),它完全满足您的需求:对输入做出一定的延迟反应。它使用事件来模仿“textchanged”。将其改编为Windows窗体非常简单。

public partial class DelayedTextBox : UserControl
{
    private DispatcherTimer eventTimer = new DispatcherTimer();
    public double TextChangedDelay
    {
        get { return eventTimer.Interval.TotalMilliseconds; }
        set { eventTimer.Interval = TimeSpan.FromMilliseconds(value); }
    }

    public delegate void DelayedTextChangedHandler(object sender, RoutedEventArgs e);
    public event DelayedTextChangedHandler DelayedTextChange;

    private object relayedSender = null;
    private RoutedEventArgs relayedE = null;

    public string Text
    {
        get
        {
            return PlainTextBox.Text;
        }

        set
        {
            PlainTextBox.Text = string.IsNullOrEmpty(value) ? string.Empty : value;
        }
    }

    //----------------------------------------------------------------------------------------------
    public TimedTextChangedTextBox()
    {
        InitializeComponent();

        TextChangedDelay = 500;
        eventTimer.Tick += new EventHandler(eventTimer_Tick);
    }

    private void StartTimer(object sender, RoutedEventArgs e)
    {
        relayedSender = sender;
        relayedE = e;
        eventTimer.Start();
    }

    private void StopTimer()
    {
        eventTimer.Stop();
        relayedSender = null;
        relayedSender = null;
    }

    private void eventTimer_Tick(object sender, EventArgs e)
    {
        StopTimer();
        if (DelayedTextChange != null)
            DelayedTextChange(relayedSender, relayedE);
    }

    private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (!maskedInput)
            ReactToInput(sender, e);
    }

    private void ReactToInput(object sender, RoutedEventArgs e)
    {
        if (!eventTimer.IsEnabled)
        {
            StartTimer(sender, e);
        }
        else
        {
            StopTimer();
            StartTimer(sender, e);
        }
    }
}

您可以使用与通常使用TextBox完全相同的控件。订阅其DelayedTextChange事件以响应用户输入。

答案 4 :(得分:0)

这显然是一篇很老的帖子,但任何寻找简化实现的人都可以从以下内容中得到一些用处:

enter image description here

using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

private Dictionary<string, string> AutoCorrectDictionary => 
    File.ReadAllLines(@"C:\AutoCorrect.txt").ToDictionary(ln => ln.Split('|')[0], ln => ln.Split('|')[1]);

private void textBox1_TextChanged(object sender, EventArgs e)
{
    var cur = textBox1.SelectionStart;
    var match = new Regex(@"[^\s]+\s$").Match(textBox1.Text.Substring(0, cur)).Value;
    if (!AutoCorrectDictionary.ContainsKey(match.Trim().ToLower())) return;
    var replaceTxt = $@"{AutoCorrectDictionary[match.Trim().ToLower()]} ";
    textBox1.Text = textBox1.Text.Remove(cur - match.Length, match.Length)
        .Insert(cur - match.Length, replaceTxt);
    textBox1.SelectionStart = cur + (replaceTxt.Length - match.Length);
}

我在这个例子中使用的字典 ("C:\AutoCorrect.txt") 包含 970 个键/值对条目,以“|”分隔,但你可以使用任何你喜欢的。在实践中,我将 AutoCorrectDictionary() 放在一个在启动时填充的静态类中。我按照我在这里的方式进行操作,以便清楚 AutoCorrectDictionary() 是什么。

享受吧!