views:

1152

answers:

8

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();
    }
}
A: 

Sorry I can't get the code tags to work right so it looks kind of jacked up. Hopefully its readable enough

+1  A: 

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.

Mark Ransom
A: 

That's what I was thinking. Any ideas on how to make this work? I tried creating a separate thread to create and destroy the progress bar window but I started getting crossthread exceptions.

Please add updates to your post and not in separate answer posts.
Nazadus
If you get crossthread-exceptions you should do something like this:if(Dispatcher.CheckAccess()){ DoSomething();}else{ Dispatcher.Invoke(DispatcherPriority.Normal, DoSomething);}
Simpzon
+3  A: 

To add what Mark says, there are two ways to fix the problem. The hack way and the proper way.

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.

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

Here is a good link to learn about this particular example. I think WPF handles things only slightly different than regular WinForms.

Nazadus
+1  A: 

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

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.

Hope this helps.

Anderson Imes
Sorry I'm still new to WPF, how do I schedule something with the dispatcher?
The link I provided contains the code for this. I'd highly encourage anyone doing WPF development to read this article fully.
Anderson Imes
I skimmed the link you gave, and it seems perfect for this question.
Mark Ransom
Hey there, thanks for the link. I've read over some of it and it makes sense for the most part. What I don't understand is, take the weather program example from the link. At the bottom of the method that simulates the program fetching data from the web, it adds a user defined method to the main UI's dispatcher. So if I'm understanding correctly, the main UI will call this when it's ready and use that method to update the UI. I could include multiple calls like this in my code that is causing the progressbar to hang right?
What I don't understand is, I don't have a method that updates anything in my gui explicitely. I just need the GUI to do its thing and automatically update the progressbar. How would I do something like that?Hope that makes sence, thanks a lot for the help
I might have missed something but what "progress" are you trying to report here? The usual usage of this control is to set minimum to something (like 0) and the maximum to something higher (say 100), and then as something you are doing in the background progresses (say, downloading a percentage of a file from the Internet) the Value property is set to an increasing value, which causes the progress bar to progress.What exactly are you doing?
Anderson Imes
A: 

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

<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

Jobi Joy
+1  A: 

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.
Simpzon
A: 

Hi

I have posted an article in CodeProject at http://www.codeproject.com/KB/WPF/WPFWaitProgressBar.aspx - can you please check out and let me know if that helps in your scenario. Thanks

Raja

Raja Lakshman