【问题标题】:WPF Overlay does not activate until after button has finishedWPF 覆盖在按钮完成后才会激活
【发布时间】:2020-05-29 09:23:46
【问题描述】:

我有一个使用 Caliburn Micro 的小型 WPF 应用程序示例。在其中,我有一个矩形叠加层,上面写着加载。我希望在加载大型任务时出现,但是直到方法完成后才会出现。我尝试过使用 Dispatch 以及其他建议,但是在按钮方法完成之前没有任何效果。以下是我当前的示例

  public async void TheActionButton()
        {
            //Application.Current.Dispatcher.Invoke(new System.Action(() => { IsLoadingMessageVisible = true; NotifyOfPropertyChange(() => IsLoadingMessageVisible); }));
            Execute.OnUIThread(new System.Action(() => { IsLoadingMessageVisible = true; NotifyOfPropertyChange(() => IsLoadingMessageVisible); }));
            await LongMethod();
        }

覆盖仅在 LongMethod() 运行完成后显示。有没有办法让它在方法运行之前显示?

【问题讨论】:

  • LongMethod 是如何实现的?尽管有签名,但它可能不是异步的。

标签: c# wpf .net-core caliburn.micro


【解决方案1】:

您还没有发布 LongMethod 的实现,所以无法说出它实际上做了什么,但我猜它没有实现为异步并阻塞 UI 线程。

您可以尝试使用Task 在后台线程上执行它:

public async void TheActionButton()
{
    IsLoadingMessageVisible = true;
    NotifyOfPropertyChange(() => IsLoadingMessageVisible);
    await Task.Run(LongMethod);
}

一个方法不会因为它返回 TaskTask<T> 并且可以等待而自动异步。

【讨论】:

  • 这是方法...我需要重新编写它以真正使其异步。现在直到我有时间我可以使用await Task.Run(async () => await Task.Delay(1)); 直到我有时间重构。感谢您的帮助!
【解决方案2】:

您应该使用 TAP(基于任务的异步编程),它可以很好地与此类用例集成。

async void TheActionButton() 
{
    IsLoadingMessageVisible = true;
    NotifyOfPropertyChange(() => IsLoadingMessageVisible);

    await LongMethod();

    IsLoadingMessageVisible = false;
    NotifyOfPropertyChange(() => IsLoadingMessageVisible);
}

注意:顺便实现你的IsLoadingMessageVisible,这样就不用每次设置属性时都调用NotifyOfPropertyChange()了。

【讨论】:

  • 感谢您的帮助。我将NotifyofPropertyChange() 添加到IsLoadingMessageVisible 的设置器中。现在函数只是public async void TheActionButton() { IsLoadingMessageVisible = true; await LongMethod(); }。但是,直到 LongMethod 完成运行后,加载消息仍然不会显示
猜你喜欢
  • 2011-03-09
  • 2011-10-06
  • 2021-07-30
  • 1970-01-01
  • 2022-08-20
  • 1970-01-01
  • 1970-01-01
  • 2014-10-14
  • 1970-01-01
相关资源
最近更新 更多