使用WPF / Caliburn进行非ui阻止任务

时间:2015-07-24 14:45:40

标签: c# wpf async-await task caliburn.micro

我尝试从外部API获取一定数量的数据,并将其填充到视图的列表中。我的设置类似于以下内容(摘录):

ShellView

<xctk:BusyIndicator IsBusy="{Binding IsBusy}">
    <ContentControl x:Name="ActiveItem" />
    ...

ShellViewModel

...
public bool IsBusy
{
    get { return _isBusy; }
    private set
    {
        _isBusy = value;
        NotifyOfPropertyChange();
    }
}

public void StartProgress()
{
    IsBusy = true;
}

public void StopProgress()
{
    IsBusy = false;
}

protected override void OnViewLoaded(object view)
{
    base.OnViewLoaded(view);
    // do some task
    ActivateItem(SomeOtherViewModel);
}

SomeOtherViewModel

public SomeOtherViewModel(IBusyIndicator busy)
{
  ....
}

protected override void OnViewLoaded(object view)
{
    base.OnViewLoaded(view);

    Task.Factory.StartNew(ACTION,
                    CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default)
                    .ConfigureAwait(true);
}

基本上,工作流程是这样的:

  1. 初始化Shell
  2. Shell - &gt; OnViewLoaded
  3. 做一些背景工作
  4. 初始化SomeOtherViewModel注入IBusyIndicatorShell为单身
  5. SomeOtherViewMode l - &gt; OnViewLoaded
  6. 做其他背景工作,例如上面的例子
  7. 然而,当我启动应用程序时,直到所有内容都被加载后才会看到视图。有办法:

    • 仅在所有内容都可见时执行操作(WPF / Caliburn)
    • 执行Task而不阻止UI /视图模型更新?

1 个答案:

答案 0 :(得分:1)

如果您希望在UI中的可见性发生变化时发生某些事情,那么您应该在UI层中对其进行编码,可以在Loaded事件或VisibilityChanged上进行编码,具体取决于您的使用案例。

如果您需要它来触发ViewModel上的操作,那么只需从UI引用ViewModel。这在MVVM中是可以接受的。

public ViewModel ViewModel
{
    get
    {
        return DataContext as ViewModel;
    }
}

public void OnLoaded()
{
    ViewModel.DoThatThing();
}

为了解决你的线程阻塞的原因,我需要看一个完整的代码示例。