UI未从EventAggregator更新

本文关键字:更新 EventAggregator 未从 UI | 更新日期: 2023-09-27 18:25:28

对于一个项目,我使用一个非常简单的进度覆盖。

它只是显示一个小的字幕进度条并覆盖屏幕。

所以在我的ShellView中我有

<Border Grid.Row="0"
        Grid.RowSpan="11"
        Grid.Column="0"
        Grid.ColumnSpan="11"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"
        Panel.ZIndex="3"
        Background="#9E000000"
        BorderBrush="Black"
        BorderThickness="3"
        Visibility="{Binding IsProgressing,
                                 Converter={StaticResource BoolToVisibility}}">
        <!-- omitted progressbar, text etc -->
</Border>

我有一个非常简单的事件,它只设置Visibility(IsProgression)绑定和一些要显示的文本。

每当我想有一个进度条时,我就发布那个事件,就像一样

_eventAggregator.Publish(new ProgressingChange(true, "Loading ..."));

到目前为止,除了一个案例:之外,这还非常有效

对于应用程序,我使用事件来导航屏幕。

所以我发布了另一个事件,比如:

_eventAggregator.Publish(new NavigationEvent(typeof(TargetViewModel)));

它只是设置目标屏幕:

public void Handle(NavigationEvent navigate)
{
    var target = _screenFactory.FromType(navigate.TargetScreen);
    this.ActivateItem(target);
}

我的一个屏幕有很多项目,大约需要3秒钟才能加载。

所以我想在加载屏幕时显示我的进度覆盖。

这是行不通的。新屏幕和叠加都是同时显示这些事件何时被组合。

这是:

_eventAggregator.Publish(new ProgressingChange(true, "Loading ..."));
_eventAggregator.Publish(new NavigationEvent(typeof(LongLoadingViewModel)));

出于调试原因,我没有将Progressing覆盖停用到正在发生的事情。

所以加载了屏幕,在大约3秒的时间里屏幕上什么都没有显示,然后显示进度覆盖和新屏幕。

我试过

  • 发布ProgressingChange事件后处于睡眠状态
  • 在两个事件处理程序中都处于睡眠状态
  • 在单独的线程上运行两个事件的发布
  • 在单独的线程上仅运行其中一个发布
  • 尝试在此处强制更新UI

我错过了什么?

这里发生了什么?

我怎样才能让它发挥作用?

-编辑-

这是我的Handler方法的代码:

public void Handle(ProgressingChange progressing)
{
    this.IsProgressing= progressing.IsProgressing;
    this.ProgressingText= progressing.ProgressingText;
    NotifyOfPropertyChange(() => IsProgressing);
    NotifyOfPropertyChange(() => ProgressingText);  
    // of course, there is Notify in the setters themselves, too
}

我使用了上面链接的源代码来强制更新UI,但不起作用

void AllowUIToUpdate() {
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate(object parameter)
{
    frame.Continue = false;
    return null;
}), null);
Dispatcher.PushFrame(frame);
}

此外,我尝试在关键部分发表文章,以迫使第一个发布将在第二个发布之前执行,但这也不起作用。

-edit2-至少显示进度覆盖的代码

_eventAggregator.Publish(new ProgressingChange(true, "Activating ..."));
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => _eventAggregator.Publish(new NavigationEvent(typeof(LongLoadingViewModel)))), DispatcherPriority.ContextIdle, null);

UI未从EventAggregator更新

这可能是一个破解,但您可以尝试先等待Border(porgress栏)呈现,然后再发布导航事件。要做到这一点,您可能能够调整此处给出的解决方案,以便在UI线程不再繁忙时执行一些代码(请参阅链接以获得完整解释):

Dispatcher.BeginInvoke(new Action(() => Trace.WriteLine("DONE!", "Rendering")), DispatcherPriority.ContextIdle, null);

如果这是有效的,那么至少你有一些东西可以让代码变得更干净。