我有以下情况:当用户将鼠标移出弹出窗口时,我想要动画发生,五秒钟之后,我想删除一个PopUp。
这是我期望执行此操作的代码:
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
答案 0 :(得分:3)
尝试使用PopUp.Dispatcher.Invoke()。这会将你的回调编组回UI线程。
答案 1 :(得分:1)
这是我在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();
}
}
}