繁体   English   中英

普通 TextBox 中的自动文本校正

[英]Automatic text correction in a normal TextBox

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

目前我有一个非常基本的更正程序。 我的 TextBoxes 应该从用户那里获得一个测量值(例如1.25 mA1.25uA1.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 中书写的秒数?

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

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

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

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

编辑:例如,为了计算时间,您可以设置一个 Timer 并每 0.5 秒触发一次。 比方说,2 秒后您调用 Correction 方法。 例如:

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;
    }
}

这是我制作的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事件以响应用户输入。

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

在此处输入图片说明

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()是什么。

享受!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM