Splash Form ProgressBar Update

Hi!

I have problems getting a ProgressBar on a splash screen to update nicely. My scenario is as follows:

* I call my main form from the Main Void with Application.Run(new Main);

* In the Main Load event I Show the splash form and sets a bol variable (m_running) to true, then I loop while the variable is true executing something like Thread.Sleep(0); (doing nothing that is)

* In a separate thread I invoke methods through delegates to add nodes to a treeview. Those nodes contain instances of others object in their tag property. When done the m_running is set to false.

* The ProgressBar on the Splash Form runs as Marquee, while m_running.

Even though I run in different threads the ProgressBar is totally still. I've tried the same thing in a testproject with a ListBox and a loop adding 10000 items. In that test the bar moves but not perfectly, but at least int moves.

Does anyone know what I'm doing wrong, can anyone point me in the right direction to get at smoothly moving ProgressBar appear on a Splasch Form while the Main form fills my treeview Do I need to supply you with code examples

/Leyan



Answer this question

Splash Form ProgressBar Update

  • Rob_IT

    You pause you load event. You should not show your Main Form before it is fully loaded. So add a Initialize method or something where you do the stuff you want to do and before you call the Initialize method you show your Splash Screen and when the Initialize method returns you Show your main and close the Splash Screen.

    I hope this is clear, if you can't get it working or you don't understand it please let me know!


  • sdgordon67

    Thanks for the answer.

    The Code project article you mentioned was one of the things I started to read when first promted with my issue. I downloaded the example in that article. As it gave me an InvalidOperationException due to Cross-Thread operations I automatically put that on the shelf. I have done some reading about the issue and what I read was that multithreading in older versions of the framework was dangerous business, because sometimes things compiled but you were not sure if you would get an Runtime error later. So I assumed that the example in that article was made in a previous version and that C# .NET 2005 now was able to detect Cross-Thread operations. Correct me if I'm wrong. I have not looked into the ApplicationContext Class just yet, but now I think I have to....or

    /Leyan


  • Jabez Gan

    No, as i sad you must Invoke method when required; otherwise you will get a Cross-Thread operation. Here is a little example:


    public void UpdateProgressBar()
    {
    // Determ if invoke is required. When it is
    // Invoke this method and return.
    if( InvokeRequired )
    {
    // Create delegate for this method and invoke it.
    MethodInvoker method = new MethodInvoker( UpdateProgressBar );
    Invoke( method );
    return;
    }

    // TODO: Add progressbar code.
    myProgressBar.Value = _percentComplete;
    }




  • Milos Cimfl

    To be honest I have troubles getting any code to be good enough. Some variants work pretty good with a ListBox1 as in my posted sample, but as soon as I try something in my real app with TreeNodes carrying data it just stops dead. So for it to update in my real app I guess the ListBox sample has to be spotless. And I cant reach that. I got a little consolation speaking to a fellow coder friend, who had troubles helping me out as well, and he's really good. So I guess its tough business to get this to work rather than I just suck. =)

    Any sample would be greatly appreciated.

    /Leyan


  • SQL 2005 Error

    Forgive my ignorance, but I'm a little comfused. I don't do any ProgressBar updates as the Style is set to Marquee, mentioned in my first post. By the way, how do I post code in nice gray box like you do :)

    This is what I got.

    Form1 (main form, with a ListBox control called listBox1):

    public partial class Form1 : Form

    {

    public string itemData = String.Empty;

    static bool m_running = false;

    public Form1()

    {

    InitializeComponent();

    }

    private void Form1_Load(object sender, EventArgs e)

    {

    System.Threading.Thread thread = new System.Threading.Thread(DoWork);

    m_running = true;

    thread.Start(m_running);

    Splash splash = new Splash();

    splash.ShowModal(ref m_running);

    while (m_running)

    {

    Thread.Sleep(0);

    }

    }

    public void DoWork(object data)

    {

    string item = String.Empty;

    for (int i = 0; i < 40000; i++)

    {

    itemData = String.Format("List item: {0}", i);

    listBox1.Invoke(new EventHandler(AddListBoxItem));

    }

    m_running = false;

    }

    public void AddListBoxItem(object sender, EventArgs e)

    {

    listBox1.Items.Add(this.itemData);

    }

    }

     

    Splash Form (one ProgressBar controll addad with the Style property set to Marquee):

    public partial class Splash : Form

    {

    public Splash()

    {

    InitializeComponent();

    }

    public void ShowModal(ref bool running)

    {

    this.Show();

    while (running)

    {

    this.Update();

    Application.DoEvents();

    }

    this.Close();

    }

       private void timer1_Tick(object sender, EventArgs e)

    {

    this.Update();

    Application.DoEvents();

    }

    }

     

    /Leyan


  • >rik<

    Pausing the Load event is never a good practice and just looping a while loop with only Thread.Sleep(0) in it or Application.DoEvents() isn't a good practice to.

    I geus you forgot to use Invoke the method that updates your ProgressBar.

    About the Splash screen, a good and prize winning article is found at code project, here.

    You can use this example Splash Screen or you can create your own ApplicationContext class, on code project you find a great example: Use the ApplicationContext Class to Fully Encapsulate Splash Screen Functionality.

    Or you can just first show your login form and then start the application with your main form:


    static void Main()
    {
    FrmLogin frmLogin = new FrmLogin();

    // If the dialog results are set to 'OK' it
    // means there was a valid login.
    if(frmLogin.ShowDialog() == DialogResult.OK)
    {
    IUserAccount user = frmLogin.UserAccount;

    Application.Run(new FrmMain(user));
    }
    }


    Normally you use events to communicate/inform your splash screen about the process.


  • ssunnergren

    PJ. van de Sande wrote:
    Thanks you very much for the code, i'm at the office right now but in an hour and a little bit i will go home. At home i have Visual Studio.NET 2005 and i will modify and post the updated code.

    I will give detailed feedback after i have runt it.

    Thanks alot. Greatly appreciated!

    /Leyan


  • MoJon1

    Thanks you very much for the code, i'm at the office right now but in an hour and a little bit i will go home. At home i have Visual Studio.NET 2005 and i will modify and post the updated code.

    I will give detailed feedback after i have runt it.


  • Splash Form ProgressBar Update