C# 如何在WPF中等待触发器采取操作
我有一个程序,其中有一个加载图像,当一个持久的行动发生。我想使用一个C# 如何在WPF中等待触发器采取操作,c#,wpf,data-binding,dispatcher,C#,Wpf,Data Binding,Dispatcher,我有一个程序,其中有一个加载图像,当一个持久的行动发生。我想使用一个ContentControl,它为操作保留一个按钮,或者显示一个正在加载的图像。我已将触发器设置为IsLoading属性,因此它可以交换内容 视图: 我不知道,Do命令将在UI线程上运行。但是,如果我更改了代码,使持久操作在后台线程上运行,它仍然不会将内容更改为空的图像,如果您没有更改属性(ˇˇˇl) 如果可以在某些后台线程上运行长时间运行的任务,请使用此选项: private void Do() { IsLoading
ContentControl
,它为操作保留一个按钮,或者显示一个正在加载的图像。我已将触发器设置为IsLoading
属性,因此它可以交换内容
视图:
我不知道,Do命令将在UI线程上运行。但是,如果我更改了代码,使持久操作在后台线程上运行,它仍然不会将内容
更改为空的图像
,如果您没有更改属性(ˇˇˇl)
如果可以在某些后台线程上运行长时间运行的任务,请使用此选项:
private void Do()
{
IsLoading = true;
// shows 1
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Task.Factory.StartNew(() =>
{
// shows 5
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
//this operation is performed on a background thread...
Thread.Sleep(1000);
}).ContinueWith(task =>
{
IsLoading = false;
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
private void Do()
{
IsLoading = true;
Task.Factory.StartNew(() =>
{
//this operation is performed on a background thread...
Thread.Sleep(1000);
}).ContinueWith(task =>
{
IsLoading = false;
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
编辑:
第一种方法有效。因此,如果仅将IsLoading
setter更改为已更改RaiseProperty(“IsLoading”)
,则它将正常工作。无需将长时间运行的任务放在后台线程中(这是我首先要避免的)。在我的特定情况下,线程.Sleep(1000)
是一个长时间运行的进程,由于可能会创建对话框窗口来通知用户异常情况,因此它也需要在UI(dispatcher)线程上运行。您应该在后台线程上执行长时间运行的操作,即线程.Sleep
:
private void Do()
{
IsLoading = true;
// shows 1
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Task.Factory.StartNew(() =>
{
// shows 5
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
//this operation is performed on a background thread...
Thread.Sleep(1000);
}).ContinueWith(task =>
{
IsLoading = false;
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
private void Do()
{
IsLoading = true;
Task.Factory.StartNew(() =>
{
//this operation is performed on a background thread...
Thread.Sleep(1000);
}).ContinueWith(task =>
{
IsLoading = false;
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
UI线程不能同时休眠和更新视图
您还需要在IsLoading
属性的setter中引发PropertyChanged
事件:
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
set { _isLoading = value; RaisePropertyChanged(); }
}
您应该在后台线程上执行长时间运行的操作,即Thread.Sleep
private void Do()
{
IsLoading = true;
// shows 1
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Task.Factory.StartNew(() =>
{
// shows 5
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
//this operation is performed on a background thread...
Thread.Sleep(1000);
}).ContinueWith(task =>
{
IsLoading = false;
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
private void Do()
{
IsLoading = true;
Task.Factory.StartNew(() =>
{
//this operation is performed on a background thread...
Thread.Sleep(1000);
}).ContinueWith(task =>
{
IsLoading = false;
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
UI线程不能同时休眠和更新视图
您还需要在IsLoading
属性的setter中引发PropertyChanged
事件:
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
set { _isLoading = value; RaisePropertyChanged(); }
}
感谢您@mm8的回答,但是图像没有显示。我离解决方案有点近了。请检查更新的问题您还需要在IsLoading属性的setter中引发PropertyChanged事件。请看我编辑的答案。我很笨。谢谢我跳过了最小示例中的一些琐碎代码谢谢你的回答@mm8,但是图像没有显示出来。我离解决方案有点近了。请检查更新的问题您还需要在IsLoading属性的setter中引发PropertyChanged事件。请看我编辑的答案。我很笨。谢谢我跳过了最小示例中的一些琐碎代码