[英]Automatic text correction in a normal TextBox
我想在我的应用程序中的一些TextBox
es 中实现自动更正。 我的意思是当用户输入文本时,几秒钟后,文本应该传递给方法,得到更正并传递回文本框。
目前我有一个非常基本的更正程序。 我的 TextBoxes 应该从用户那里获得一个测量值(例如1.25 mA
、 1.25uA
、 1.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.