如何显示等待对话框,直到非 UI 线程按照 MVVM 设计模式在 WPF 应用程序中工作

本文关键字:MVVM 线程 设计模式 工作 应用程序 WPF UI 显示 何显示 等待 对话框 | 更新日期: 2023-09-27 17:55:25

我正在开发一个遵循MVVM设计模式的WPF应用程序。对于线程,我打算使用后台工作者。从视图模型中,我需要启动线程来执行耗时的操作。请建议我如何显示等待对话框,直到线程执行。如果可能,请提供示例代码。问候阿尼班

如何显示等待对话框,直到非 UI 线程按照 MVVM 设计模式在 WPF 应用程序中工作

您可以向 ViewModel 添加一个属性,指示后台工作线程(或其他异步操作)正忙。

视图可以将绑定绑定绑定到此属性以显示进度条或其他繁忙指示器。

只需确保正确设置和重置属性即可。

编辑

有关在 WPF 中创建模式对话框,请参阅此问题/解答:如何在 WPF 中创建模式对话框?

作为替代方法,您可以使用此设置(伪代码):

<Window>
    <Grid>
        <Grid x:Name="regularContent">
        </Grid>
        <Grid x:Name="Overlay" Visibility="Collapsed">
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                <Progressbar Value="{Binding Path=Progress}" />
            </StackPanel>
        </Grid>
    </Grid>
</Window>

代码隐藏:

private void ShowPopup()
{
    RegularContent.IsEnabled = false;
    Overlay.Visibility = Visibility.Visible;
}
private void ClosePopup()
{
    RegularContent.IsEnabled = true;
    Overlay.Visibility = Visibility.Collapsed;
}

请确保禁用常规内容以防止用户按 Tab 键转到它。

您可以使用相同的结构来遮挡视图的一部分,而不是像我所做的那样完全阻塞它。

进度条绑定到的视图模型上的进度属性应在 UI 线程上修改。如果您使用的是后台工作程序,则会自动完成此操作,因为 ReportProgress 事件是在 UI 线程上引发的。

如果使用其他方式创建工作线程,请确保使用调度程序更新 Progress 属性。

我在Windows Phone中使用了它:

private readonly BackgroundWorker worker = new BackgroundWorker();
private PerformanceProgressBar loader = new PerformanceProgressBar();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
   bar.IsIndeterminate = true;
   Bar.Enabled = true;
}
private void worker_RunWorkerCompleted(object sender, 
                                       RunWorkerCompletedEventArgs e)
{
   bar.Enabled = false;
}
worker.RunWorkerAsync();

如果要定义 MVVM 结构: 性能进度栏"无效的跨线程访问"异常

当然,类似的用户控件也存在于WPF中: http://wpftoolkit.codeplex.com/wikipage?title=Extended%20WPF%20Toolkit%20Controls

最简单的方法是使用 wpf busyindicator(http://elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/)。

您可以将其绑定到模型模型中的某些thread_is_busy_flag_property(我更喜欢通过定位器模式通过应用程序范围的资源访问的单调 - 它很容易在 xaml 和模型视图/代码隐藏之间共享)。

只是在设置此标志时不要忘记线程安全(或者您可以使用 AutoResetEvent/ManualResetEvent 来捕获后台操作结束)。我建议使用TPL和任务(更健壮的方式)而不是BackgroundWorker/QueueUserWorkItem。