Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WPF中等待触发器采取操作_C#_Wpf_Data Binding_Dispatcher - Fatal编程技术网

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事件。请看我编辑的答案。我很笨。谢谢我跳过了最小示例中的一些琐碎代码