简体   繁体   English

如何保持ProgressBar不确定的动画

[英]How to keep ProgressBar Indeterminate animating

I've been learning about how this issue is confronted via Threads ( BackgroundWorker and others) and how to keep the UI responsive. 我一直在学习如何通过Threads( BackgroundWorker等)解决这个问题,以及如何使UI保持响应。 I've managed to do so but then I realized that is not what I want. 我设法做到了,但是后来我意识到这不是我想要的。 What I need actually is just to display an animating ProgressBar while a long operation is performed. 我真正需要的只是在执行长时间的操作时显示动画的ProgressBar (I don't need/want to update the UI because in that operation I'm exporting all graphical representation and the plotter is updated constantly). (我不需要/不想更新UI,因为在该操作中,我将导出所有图形表示,并且绘图仪会不断更新)。

I have thought about a Dialog popping-up with the progress bar while the operation is being performed. 我考虑过在执行操作时弹出带有进度条的对话框。 The problem is that I get this exception: 问题是我得到了这个异常:

The calling thread cannot access this object because a different thread owns it

There are plenty of questions about this and the answer is to use Dispatcher : 关于此有很多问题,答案是使用Dispatcher

            Dispatcher.CurrentDispatcher.Invoke(() => myOperation(), DispatcherPriority.Normal);

Here is what've done: 这是完成的操作:

I'm using Modern UI, there is a Dialog called ModernDialog, it's just a fancy dialog: 我正在使用Modern UI,有一个名为ModernDialog的对话框,它只是一个漂亮的对话框:

  class DialogProgress
{
    public ModernDialog progressDlg = new ModernDialog();

    public DialogProgress()
    {
        ProgressBar bar = new ProgressBar();
        bar.IsIndeterminate = true;
        bar.Width = 150;
        StackPanel content = new StackPanel();
        content.Children.Add(bar);
        progresoDlg.Content = content ;

        //Thread paralel = new Thread(() => myOperation());
        //paralel.SetApartmentState(ApartmentState.STA);
        //paralel.Start();
        Dispatcher.CurrentDispatcher.Invoke(() => myOperation(), DispatcherPriority.Normal);
    }

    void myOperation()
    {
        progresoDlg.ShowDialog();
    }
}

I know I'm mixing stuff there, there are Threads and Dispatcher, but I can't figure out how to use them. 我知道我在混合东西,有线程和分派器,但我不知道如何使用它们。

Here is how I call this dialog: 这是我称呼此对话框的方式:

public void MyLongMethod()
{
        DialogProgress progress = new DialogProgress();
}

If I use only Dispatcher, the dialog shows up and the bar is being animated but MyLongMethod is not working (it starts after closing the dialog). 如果我仅使用Dispatcher,则会显示对话框,并且该栏正在设置动画,但MyLongMethod无法正常工作(它在关闭对话框后开始)。

If I use Threads I get the mentioned exception. 如果我使用线程,则会遇到上述异常。

How can I solve this problem? 我怎么解决这个问题?

(PD using a dialog Is only a suggestion, I would be happy too if the progress bar is in the UI and I switch the visibility when the long method starts/ends) (使用对话框的PD只是一个建议,如果进度条位于UI中,并且在long方法开始/结束时切换可见性,我也很高兴)

    Dispatcher.CurrentDispatcher.Invoke(...);

This goes wrong because you used Invoke(), it will not return until the invoked method finished running. 这是错误的,因为您使用了Invoke(),在调用的方法完成运行之前它不会返回。 Which will take a while, ShowDialog() is a blocking call that doesn't complete until the user closes the dialog. 这将需要一段时间,ShowDialog()是一个阻塞调用,直到用户关闭对话框后才完成。

The simple workaround is to use BeginInvoke() instead. 一个简单的解决方法是改为使用BeginInvoke()。

Assuming ModernDialog is a WPF Window , the ShowDialog method does not return until it's closed. 假设ModernDialog是WPF Window ,则ShowDialog方法在关闭之前不会返回。 Invoke also doesn't return until the operation is called and returns. 调用也不会返回,直到调用操作并返回。 You need to either use Show instead of ShowDialog , or call it with BeginInvoke instead of Invoke . 您需要使用Show而不是ShowDialog ,或者使用BeginInvoke而不是Invoke I would use Show , because ShowDialog doesn't really make sense unless you are waiting for the user to respond by clicking a dialog button. 我将使用Show ,因为ShowDialog并没有真正的意义,除非您等待用户通过单击对话框按钮做出响应。

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

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