我想扩展TextBox控件,因此它将触发具有指定延迟的自定义事件。
这是我到目前为止的代码:
public class DelayTextBox : TextBox
{
private Timer _delayTimer;
private int _threshold = 1000;
public DelayTextBox()
{
_delayTimer = new Timer(_threshold);
_delayTimer.Elapsed += new ElapsedEventHandler(_delayTimer_Elapsed);
}
public int Delay
{
set { _threshold = value; }
}
private void _delayTimer_Elapsed(object sender, ElapsedEventArgs e)
{
_delayTimer.Stop();
RaiseDelayedTextChangedEvent();
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
_delayTimer.Stop();
_delayTimer.Start();
}
private static readonly RoutedEvent DelayedTextChangedEvent = EventManager.RegisterRoutedEvent(
"DelayedTextChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DelayTextBox));
public event RoutedEventHandler DelayedTextChanged
{
add { AddHandler(DelayedTextChangedEvent, value); }
remove { RemoveHandler(DelayedTextChangedEvent, value); }
}
private void RaiseDelayedTextChangedEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent);
RaiseEvent(newEventArgs);
}
}
问题在于每当我触发RaiseDelayedTextChangedEvent()时,我都会收到异常,告诉我
'调用线程因为不同而无法访问此对象 线程拥有它。'
此处抛出异常:
private void RaiseDelayedTextChangedEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent);
RaiseEvent(newEventArgs);
} <---- Here
答案 0 :(得分:2)
那是因为Timer在不同的线程中运行,并且无法从该线程修改UI(就像你的异常所说)。请尝试使用DispatcherTimer。您可以在此处了解详情:http://code.dortikum.net/2008/08/06/timer-vs-dispatchertimer-in-wpf/
答案 1 :(得分:0)
您需要使用调度程序在STA线程中引发事件。
本文解释了您遇到的线程问题http://www.switchonthecode.com/tutorials/working-with-the-wpf-dispatcher
private void RaiseDelayedTextChangedEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent);
this.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
(UpdateTheUI)delegate(RoutedEventArgs eArgs)
{
RaiseEvent(eArgs);
}, newEventArgs );
}