CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: Redraw problem.

  1. #1
    Join Date
    Nov 2006
    Posts
    11

    Redraw problem.

    This is part of my code:

    Code:
            private void browse_button_Click(object sender, EventArgs e)
            {
                toolStripProgressBar1.Value = 0;
                toolStripProgressBar1.Minimum = 0;
                toolStripProgressBar1.Step = 1;
                label_count.Text = "";
                folderBrowserDialog.RootFolder = System.Environment.SpecialFolder.MyComputer;
                folderBrowserDialog.ShowNewFolderButton = false;
                toolStripStatusLabel1.Invalidate();
                DialogResult result = folderBrowserDialog.ShowDialog();
                if (result == DialogResult.OK)
                {
                    toolStripStatusLabel1.Text = "Loading... Please wait";
                    toolStripStatusLabel1.Invalidate();
                    listbox.Items.Clear();
                    string foldername = folderBrowserDialog.SelectedPath;
                    selected_path.Text = foldername;
                    int count = DirCount(foldername);
                    toolStripProgressBar1.Maximum = count;
                    DirSearch(foldername);
                }
                else if (result == DialogResult.Cancel)
                {
                    toolStripStatusLabel1.Text = "";
                }
            }
    
            void DirSearch(string sDir)
            {
                try
                {
                    foreach (string d in Directory.GetDirectories(sDir))
                    {
                        DirSearch(d);
                        string name = d.Substring(d.LastIndexOf("\\") + 1);
                        {
                            if (name.ToLower().Contains("cd"))
                            { }
                            else if (name.ToLower().Contains("artwork"))
                            { }
                            else if (name.ToLower().Contains("disc"))
                            { }
                            else if (name.ToLower().Contains("cover"))
                            { }
                            else if (name.ToLower().Contains("label"))
                            { }
                            else if (name.ToLower().Contains("disk"))
                            { }
                            else
                            {
                                if (!Regex.IsMatch(name, numbers))
                                {
                                    name = name.Replace("_", " ");
                                    listbox.Items.Add(name);
                                    toolStripProgressBar1.PerformStep();
                                    label_count.Text = listbox.Items.Count.ToString();
                                    label_count.Invalidate();
                                    double percent = 100.0 * toolStripProgressBar1.Value/ toolStripProgressBar1.Maximum;
                                    toolStripStatusLabel1.Text = ((int)percent).ToString();
                                   toolStripStatusLabel1.Invalidate();
                                }
                            }
                        }
                    }
                }
                catch (System.Exception excpt)
                {
                    MessageBox.Show(excpt.Message);
                }
                label_count.Text = listbox.Items.Count.ToString();
                toolStripStatusLabel1.Text = "Done!";
            }
            int DirCount(string sDir)
            {
                int count = 0;
                try
                {
                    foreach (string d in Directory.GetDirectories(sDir))
                    {
                        count += DirCount(d);
                        string name = d.Substring(d.LastIndexOf("\\") + 1);
                        {
                            if (name.ToLower().Contains("cd"))
                            { }
                            else if (name.ToLower().Contains("artwork"))
                            { }
                            else if (name.ToLower().Contains("disc"))
                            { }
                            else if (name.ToLower().Contains("cover"))
                            { }
                            else if (name.ToLower().Contains("label"))
                            { }
                            else if (name.ToLower().Contains("disk"))
                            { }
                            else
                            {
                                if (!Regex.IsMatch(name, numbers))
                                {
                                    count++;
                                }
                            }
                        }
                    }
                }
                catch (System.Exception excpt)
                {
                    MessageBox.Show(excpt.Message);
                }
                return count;
            }
    The problem is, that the toolStripStatusLabel1 nor the label_count don't get updated with the "Loading...Please wait", or the percentage counter during the search/count of the folders. First I had it without the Invalidate() switch, but was then suggested to add it, but that didn't help.

    Any bright heads got an idea what might be wrong?

  2. #2
    Join Date
    Oct 2004
    Location
    Rocket City
    Posts
    220

    Re: Redraw problem.

    Sometimes Microsoft notoriously gives us things to use (Invalidate) and then chooses to ignore them at will. In many cases when using a loop we must resort to Application.DoEvents() to get a reasonable gui response.
    Code:
    someloop
    {
        // calculate percent...
        toolStripStatusLabel1.Text = Convert.ToInt32(percent).ToString();
        Application.DoEvents();
    }

  3. #3
    Join Date
    Jun 2008
    Posts
    2,477

    Re: Redraw problem.

    Quote Originally Posted by zips View Post
    Sometimes Microsoft notoriously gives us things to use (Invalidate) and then chooses to ignore them at will. In many cases when using a loop we must resort to Application.DoEvents() to get a reasonable gui response.
    Code:
    someloop
    {
        // calculate percent...
        toolStripStatusLabel1.Text = Convert.ToInt32(percent).ToString();
        Application.DoEvents();
    }

    This is bad advice. Can you show me an example where Invalidate( ) does not work? You should never have to use DoEvents( ) in a .NET application, your statement shows that you do not understand how the Windows message queue works. You should be performing your calculations in a separate thread (i.e., not the UI thread) and updating the UI by using a delegate which the secondary thread calls at fixed intervals. Take some time to look into the BackgroundWorker class.

    Here is an article on the Windows message queue. Once you read that you should have a better understanding of why your redraw messages were not being processed reliably.

    http://en.wikipedia.org/wiki/Microsoft_Message_Queuing
    Last edited by BigEd781; October 1st, 2009 at 01:06 PM.

  4. #4
    Join Date
    Nov 2006
    Posts
    11

    Re: Redraw problem.

    My initial thought was also to run the DirSearch in a seperate thread, but I haven't worked with backgroundworker before, therefore I asked.

  5. #5
    Join Date
    Oct 2004
    Location
    Rocket City
    Posts
    220

    Re: Redraw problem.

    Quote Originally Posted by BigEd781
    Can you show me an example where Invalidate( ) does not work?
    Invalidate, Paint, Redraw, Update, etc all routinely fail to work within a tight loop - the messages are 'postponed' until Windows arrives at a 'more opportune' time. So, if the point is to update something in the gui while it is changing within a loop, Invalidate alone is useless - only the last message will be seen. Thanks for the link.

  6. #6
    Join Date
    Oct 2004
    Location
    Rocket City
    Posts
    220

    Re: Redraw problem.

    Quote Originally Posted by BigEd781
    You should never have to use DoEvents( ) in a .NET application...
    MSDN Library for Visual Studio 2008, under Application.DoEvents Method says:
    Typically, you use this method in a loop to process messages.

  7. #7
    Join Date
    Jun 2008
    Posts
    2,477

    Re: Redraw problem.

    Quote Originally Posted by zips View Post
    MSDN Library for Visual Studio 2008, under Application.DoEvents Method says:
    It is bad practice and can lead to re-entrancy issues. I know what it is used for, but there is no reason to use it in the .NET world when it is so easy to set up a separate thread for processing.
    Last edited by BigEd781; October 1st, 2009 at 02:35 PM. Reason: .

  8. #8
    Join Date
    Jun 2001
    Location
    Melbourne/Aus (C# .Net 4.0)
    Posts
    686

    Re: Redraw problem.

    I believe there is only ever one WM_PAINT (and WM_TIMER) message on the Message Queue and it is always at the back of the queue.
    Rob
    -
    Ohhhhh.... Old McDonald was dyslexic, E O I O EEEEEEEEEE.......

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured