开发者

Delayed firing of custom event

I want to extend the TextBox control, so it will fire a custom event with a specified delay.

Here is the code i have so far:

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

    pr开发者_JAVA百科ivate void RaiseDelayedTextChangedEvent()
    {
        RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent);
        RaiseEvent(newEventArgs);
    }
}

The problem is that whenever i fire RaiseDelayedTextChangedEvent(), i get an exception, telling me

'The calling thread cannot access this object because a different thread owns it.'

The exception is thrown here:

private void RaiseDelayedTextChangedEvent()
    {
        RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent);
        RaiseEvent(newEventArgs);
    } <---- Here


That's because the Timer runs in a different thread, and UI cannot be modified from that thread (like your exception says). Try using a DispatcherTimer instead. You can learn more about it here: http://code.dortikum.net/2008/08/06/timer-vs-dispatchertimer-in-wpf/


You need to use the dispatcher to raise the event in the STA Thread.

This article explains the threading issues you are having 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 );

    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜