Задержка срабатывания пользовательского события - PullRequest
0 голосов
/ 12 июля 2011

Я хочу расширить элемент управления 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

Ответы [ 2 ]

2 голосов
/ 12 июля 2011

Это потому, что Timer работает в другом потоке, и пользовательский интерфейс не может быть изменен из этого потока (как говорит ваше исключение).Попробуйте вместо этого использовать DispatcherTimer.Вы можете узнать больше об этом здесь: http://code.dortikum.net/2008/08/06/timer-vs-dispatchertimer-in-wpf/

0 голосов
/ 12 июля 2011

Вам нужно использовать диспетчер, чтобы вызвать событие в потоке 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 );

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...