I can't get my progress bar to work. Any help is much appreciated!
我无法让我的进度条工作。任何帮助深表感谢!
Here's the code:
这是代码:
<Window x:Class="BulkSAConfigureControl.BulkSaProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Please Wait.." Height="60" Width="300" WindowStyle="ToolWindow" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<ProgressBar Name="progressBar" IsIndeterminate="True">
<ProgressBar.Resources>
<ResourceDictionary Source="/PresentationFramework.Aero;v3.0.0.0;31bf3856ad364e35;component/themes/aero.normalcolor.xaml" />
</ProgressBar.Resources>
</ProgressBar>
.
public class ProgressBarClass : Window
{
public ProgressBarClass()
{
InitializeComponent();
}
public void StartProgressBar()
{
Duration d = new Duration(TimeSpan.FromSeconds(5));
DoubleAnimation anim = new DoubleAnimation(100.0, d);
progressBar.BeginAnimation(ProgressBar.ValueProperty, anim);
this.Show();
}
public void StopProgressBar()
{
this.Close();
}
}
.
public class DoSomething : UserControl
{
public void DoSomeStuff()
{
ProgressBarClass pBar = new ProgressBarClass();
pBar.StartProgressBar();
// Do some stuff here
pBar.StopProgressBar();
}
}
5 个解决方案
#1
To add what Mark says, there are two ways to fix the problem. The hack way and the proper way.
要添加Mark所说的内容,有两种方法可以解决问题。黑客的方式和正确的方式。
The proper way is to use threading, such as a BackgroundWorker. You will likely end up using control.BeginInvoke to handle updating the GUI thread.
正确的方法是使用线程,例如BackgroundWorker。您最终可能会使用control.BeginInvoke来处理更新GUI线程。
The hack way is to call Application.DoEvents in your loop. I call this the hack because it only partially works. For example, if you're doing a tight loop that has lots of little quick instructions then it will work fine'ish. If you're doing a loop in which your instructions take a while, this will not work (such as making a huge sql query to a database).
黑客的方法是在循环中调用Application.DoEvents。我称之为黑客,因为它只是部分有效。例如,如果你正在进行一个有很多快速指令的紧密循环,那么它将很好地工作。如果您正在执行一个循环,其中您的指令需要一段时间,这将无法工作(例如对数据库进行大量的SQL查询)。
Here is a good link to learn about this particular example. I think WPF handles things only slightly different than regular WinForms.
这是了解这个特定示例的好链接。我认为WPF只处理与常规WinForms略有不同的东西。
#2
This answer isn't specific to C# or WPF, but with Windows in general. A progress bar will only update if you are processing Windows messages. If you're running a tight CPU loop with no UI interaction, the progress bar never gets a chance to repaint.
这个答案不是特定于C#或WPF,而是一般的Windows。只有在处理Windows消息时,才会更新进度条。如果您在没有UI交互的情况下运行紧凑的CPU循环,则进度条永远不会有机会重新绘制。
#3
I'm not sure this is your problem (I don't know much about the animations... I've only used the progress bar by incremening the "Value" property), but I think most of the suggestions here ignore the UI threading model introduced in WPF: Threading in WPF
我不确定这是你的问题(我对动画知之甚少......我只是通过增加“值”属性来使用进度条),但我认为这里的大多数建议都忽略了UI WPF中引入的线程模型:WPF中的线程化
If you have a loop of some sort (I don't think you do, judging by your code, but I could be wrong), then you'll want to schedule each iteration of your loop with the Dispatcher... this way WPF can intersperse your code executing with the UI events it needs to do to repaint properly.
如果你有某种循环(我不认为你这样做,从你的代码判断,但我可能是错的),那么你将需要使用Dispatcher计划循环的每次迭代...这样WPF可以通过正确重新绘制所需的UI事件来散布您的代码执行。
Hope this helps.
希望这可以帮助。
#4
I observed two things:
我发现了两件事:
- If you set IsIndeterminate="True" for the progressbar, it will not walk from 0 to 100% but just run left-right-left again and again (some K.I.T.T.-effect), you will want this only if you don't know, where you are in your progress timeline. (with certain styles you even see nothing on the progress bar, but on Vista-default it shows some green shade going from side to side)
- If you want to set your progress-value from the background-thread, you should do this by using a backgroundworker for your action and then use the method called "ReportProgress" after certain milestones. This way the UI will perform an update to show your new progress.
如果为进度条设置IsIndeterminate =“True”,它将不会从0到100%走,但只是一次又一次地左右运行(一些KITT效果),只有在你不知道的情况下才会想要这个,您在进度时间表中的位置。 (某些样式你甚至在进度条上看不到任何内容,但在Vista-default上它显示出一些绿色阴影从一边到另一边)
如果要从后台线程设置进度值,则应通过使用后台工作程序执行此操作,然后在某些里程碑后使用名为“ReportProgress”的方法。这样,UI将执行更新以显示您的新进度。
#5
I assume you are asking a basic question of making a Progress bar working from the code behind? and Threading is not your problem I guess. It is very simple in WPF to make a progress bar works. Hope you will be having some values coming from your background process as a percentage or something. Just set the ProgressBar.Value property and it will do the rest. A test app below
我假设你问一个基本问题,即使用后面的代码使进度条工作?我猜,线程不是你的问题。在WPF中使进度条工作非常简单。希望你的背景过程中会有一些价值观或百分比。只需设置ProgressBar.Value属性,它将完成剩下的工作。下面的测试应用程序
<ProgressBar x:Name="progress" MouseDown="Window_MouseDown" VerticalAlignment="Top" Height="93"/>
at C#
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
progress.Value = progress.Value+1;
}
And write the following code in the code behind and keep clicking on the ProgressBar when the app runs
并在后面的代码中编写以下代码,并在应用程序运行时继续单击ProgressBar
#1
To add what Mark says, there are two ways to fix the problem. The hack way and the proper way.
要添加Mark所说的内容,有两种方法可以解决问题。黑客的方式和正确的方式。
The proper way is to use threading, such as a BackgroundWorker. You will likely end up using control.BeginInvoke to handle updating the GUI thread.
正确的方法是使用线程,例如BackgroundWorker。您最终可能会使用control.BeginInvoke来处理更新GUI线程。
The hack way is to call Application.DoEvents in your loop. I call this the hack because it only partially works. For example, if you're doing a tight loop that has lots of little quick instructions then it will work fine'ish. If you're doing a loop in which your instructions take a while, this will not work (such as making a huge sql query to a database).
黑客的方法是在循环中调用Application.DoEvents。我称之为黑客,因为它只是部分有效。例如,如果你正在进行一个有很多快速指令的紧密循环,那么它将很好地工作。如果您正在执行一个循环,其中您的指令需要一段时间,这将无法工作(例如对数据库进行大量的SQL查询)。
Here is a good link to learn about this particular example. I think WPF handles things only slightly different than regular WinForms.
这是了解这个特定示例的好链接。我认为WPF只处理与常规WinForms略有不同的东西。
#2
This answer isn't specific to C# or WPF, but with Windows in general. A progress bar will only update if you are processing Windows messages. If you're running a tight CPU loop with no UI interaction, the progress bar never gets a chance to repaint.
这个答案不是特定于C#或WPF,而是一般的Windows。只有在处理Windows消息时,才会更新进度条。如果您在没有UI交互的情况下运行紧凑的CPU循环,则进度条永远不会有机会重新绘制。
#3
I'm not sure this is your problem (I don't know much about the animations... I've only used the progress bar by incremening the "Value" property), but I think most of the suggestions here ignore the UI threading model introduced in WPF: Threading in WPF
我不确定这是你的问题(我对动画知之甚少......我只是通过增加“值”属性来使用进度条),但我认为这里的大多数建议都忽略了UI WPF中引入的线程模型:WPF中的线程化
If you have a loop of some sort (I don't think you do, judging by your code, but I could be wrong), then you'll want to schedule each iteration of your loop with the Dispatcher... this way WPF can intersperse your code executing with the UI events it needs to do to repaint properly.
如果你有某种循环(我不认为你这样做,从你的代码判断,但我可能是错的),那么你将需要使用Dispatcher计划循环的每次迭代...这样WPF可以通过正确重新绘制所需的UI事件来散布您的代码执行。
Hope this helps.
希望这可以帮助。
#4
I observed two things:
我发现了两件事:
- If you set IsIndeterminate="True" for the progressbar, it will not walk from 0 to 100% but just run left-right-left again and again (some K.I.T.T.-effect), you will want this only if you don't know, where you are in your progress timeline. (with certain styles you even see nothing on the progress bar, but on Vista-default it shows some green shade going from side to side)
- If you want to set your progress-value from the background-thread, you should do this by using a backgroundworker for your action and then use the method called "ReportProgress" after certain milestones. This way the UI will perform an update to show your new progress.
如果为进度条设置IsIndeterminate =“True”,它将不会从0到100%走,但只是一次又一次地左右运行(一些KITT效果),只有在你不知道的情况下才会想要这个,您在进度时间表中的位置。 (某些样式你甚至在进度条上看不到任何内容,但在Vista-default上它显示出一些绿色阴影从一边到另一边)
如果要从后台线程设置进度值,则应通过使用后台工作程序执行此操作,然后在某些里程碑后使用名为“ReportProgress”的方法。这样,UI将执行更新以显示您的新进度。
#5
I assume you are asking a basic question of making a Progress bar working from the code behind? and Threading is not your problem I guess. It is very simple in WPF to make a progress bar works. Hope you will be having some values coming from your background process as a percentage or something. Just set the ProgressBar.Value property and it will do the rest. A test app below
我假设你问一个基本问题,即使用后面的代码使进度条工作?我猜,线程不是你的问题。在WPF中使进度条工作非常简单。希望你的背景过程中会有一些价值观或百分比。只需设置ProgressBar.Value属性,它将完成剩下的工作。下面的测试应用程序
<ProgressBar x:Name="progress" MouseDown="Window_MouseDown" VerticalAlignment="Top" Height="93"/>
at C#
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
progress.Value = progress.Value+1;
}
And write the following code in the code behind and keep clicking on the ProgressBar when the app runs
并在后面的代码中编写以下代码,并在应用程序运行时继续单击ProgressBar