Silverlight: потоки / отложенные действия / асинхронные вызовы / события - PullRequest
1 голос
/ 26 февраля 2009

У меня есть следующий сценарий: когда пользователь перемещает мышь из всплывающего окна, я хочу, чтобы анимация происходила, а через пять секунд я хочу удалить всплывающее окно.

Это код, с которым я ожидал сделать это:

private bool leftPopup = false;
public void AnimatePopupOut(object sender, MouseEventArgs e)
{
   myAnim.Begin();
   (new Thread(new ThreadStart(delayedRemovePopup))).Start();
}

private void delayedRemovePopup()
{
   leftPopup = true;
   Thread.Sleep(5000);
   PopUp.IsOpen = false;
}

Первая строка "leftPopup = true" в порядке, но третья, "PopUp.IsOpen = false", дает мне исключение нарушения прав доступа, вероятно, потому, что этот объект принадлежит потоку GUI. Есть ли способ получить доступ к свойству PopUp.IsOpen? Если нет, есть ли другой способ, которым я могу вызвать событие через некоторое время, чтобы сделать это?

Приветствия

Nik

Ответы [ 2 ]

3 голосов
/ 26 февраля 2009

Попробуйте использовать PopUp.Dispatcher.Invoke (). Это перенаправит ваш звонок обратно в поток пользовательского интерфейса.

1 голос
/ 18 декабря 2012

Вот трюк, который я сделал в WPF. Он портирован для использования в Silverlight и зависает от класса Dispacher. Я не знаю об ответе Мориса, потому что я не вижу метод «Вызвать» в SL5. Я вижу BeginInvoke, который бесполезен, когда дело касается отложенных действий.

Использование: Вы должны включить пространство имен System.Windows в свой файл кода, иначе этот метод расширения не появится.

// lets say you want to enable a control 1 second after a save event
// lets say you just want to prevent click happy users from going crazy
//   This code assumes you disabled the button on the click event
Button b = this.idButton1;
b.Dispatcher.DelayInvoke(TimeSpan.FromSeconds(1), () => { b.Enabled = true; });

Вот и все. Всего одна строка кода делает свое дело. Ниже приведен класс расширения, который делает возможным приведенный выше код.

using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace System.Windows {

    public static class DispatcherExtensions {

        public static void DelayInvoke<TArg1, TArg2, TArg3>(this Dispatcher dispatcher, TimeSpan delay, Action<TArg1, TArg2, TArg3> action, TArg1 arg1, TArg2 arg2, TArg3 arg3) {
            dispatcher.DelayInvoke(delay, (Delegate)action, arg1, arg2, arg3);
        }

        public static void DelayInvoke<TArg1, TArg2>(this Dispatcher dispatcher, TimeSpan delay, Action<TArg1, TArg2> action, TArg1 arg1, TArg2 arg2) {
            dispatcher.DelayInvoke(delay, (Delegate)action, arg1, arg2);
        }

        public static void DelayInvoke<TArg1>(this Dispatcher dispatcher, TimeSpan delay, Action<TArg1> action, TArg1 arg1) {
            dispatcher.DelayInvoke(delay, (Delegate)action, arg1);
        }

        public static void DelayInvoke(this Dispatcher dispatcher, TimeSpan delay, Action action) {
            dispatcher.DelayInvoke(delay, (Delegate)action);
        }

        public static void DelayInvoke(this Dispatcher dispatcher, TimeSpan delay, Delegate del, params object[] args) {

            if (dispatcher == null)
                throw new NullReferenceException();
            if (delay < TimeSpan.Zero)
                throw new ArgumentOutOfRangeException("delay");
            if (del == null)
                throw new ArgumentNullException("del");

            var task = new Task(() => { Thread.Sleep(delay); });

            task.ContinueWith((t) => { dispatcher.BeginInvoke(del, args); });
            task.Start();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...