简体   繁体   English

如何显示等待对话框,直到遵循MVVM设计模式的WPF应用程序中的非ui线程正在工作?

[英]How to display wait dialog till a non ui thread is working in a WPF application following MVVM design pattern?

I am developing a WPF application that follows MVVM design pattern. 我正在开发遵循MVVM设计模式的WPF应用程序。 For threading I intend to use Backgroundworker. 对于线程,我打算使用Backgroundworker。 From viewmodels,I need to initiate threads to perform time taking opeartions.Please suggest me how to display an wait dialog until the thread is performing. 从视图模型,我需要启动线程来执行耗时的操作。请建议我如何显示等待对话框,直到线程执行为止。 If possible please provide a sample code. 如果可能,请提供示例代码。 Regards, Anirban 问候,阿尼班

You could add a property to the ViewModel that indicates that the backgroundworker (or other asynchronous action) is busy. 您可以向ViewModel添加一个属性,该属性指示backgroundworker(或其他异步操作)正忙。

A View can bind bind to this property to show a progressbar or other busy indicator. 视图可以绑定绑定到此属性以显示进度栏或其他繁忙指示器。

Just make sure you set and reset the property correctly. 只要确保您正确设置和重置属性即可。

EDIT 编辑

See this question/answer for making a modal dialog in WPF: How do make modal dialog in WPF? 有关在WPF中创建模式对话框的信息,请参见以下问题/答案: 如何在WPF中创建模式对话框?

As an alternative you could use this setup (pseudo code): 或者,您可以使用以下设置(伪代码):

<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>

Code behind: 后面的代码:

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

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

Make sure you disable the regular content to prevent the user from tabbing to it. 确保禁用常规内容,以防止用户切换到常规内容。

You can use the same structure to blockout a part of the View instead of blocking it entirely as I have done. 您可以使用相同的结构来阻塞View的一部分,而不是像我一样完全阻塞它。

The Progress property on the ViewModel that the ProgressBar is bound to should be modified on the UI thread. 应在UI线程上修改ProgressBar绑定到的ViewModel上的Progress属性。 If you are using a backgroundworker that will be done automatically because the ReportProgress event is raised on the UI thread. 如果您正在使用backgroundworker,则它将自动完成,因为UI线程上引发了ReportProgress事件。

If you use a different way of creating a worker thread make sure you use the dispatcher to update the Progress property. 如果使用其他方式创建工作线程,请确保使用分派器更新Progress属性。

I used it in Windows Phone : 我在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();

If you want to define a MVVM structure : PerformanceProgressBar "Invalid cross-thread access" exception 如果要定义MVVM结构,请执行以下操作: PerformanceProgressBar“无效的跨线程访问”异常

Of course an similar user control also exists in WPF : http://wpftoolkit.codeplex.com/wikipage?title=Extended%20WPF%20Toolkit%20Controls 当然,WPF中也存在类似的用户控件: http ://wpftoolkit.codeplex.com/wikipage?title = Extended%20WPF%20Toolkit%20Controls

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

You can bind it to some thread_is_busy_flag_property in your model model (I prefer it in some singletone accessible through application-wide resource via locator pattern - it's easy to share across xaml and model view/code behind). 您可以将其绑定到模型模型中的某些thread_is_busy_flag_property(我更喜欢通过定位器模式通过应用程序范围的资源访问某些单调模式中的单调-易于在xaml和模型视图/代码之间共享)。

Just don't forget about thread safety when setting this flag (or you can use AutoResetEvent/ManualResetEvent to catch background operation ends). 只是在设置此标志时不要忘记线程安全性(否则您可以使用AutoResetEvent / ManualResetEvent来捕获后台操作结束)。 And I suggest to use TPL and tasks (more robust way) instead of BackgroundWorker/QueueUserWorkItem. 我建议使用TPL和任务(更可靠的方法)代替BackgroundWorker / QueueUserWorkItem。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM