views:

95

answers:

3

Yay I finally thought of a title!

I have a foreach loop that iterates the ListViewItems and does something with each item. But the problem is not that it doesn't do the work in the loop, but it simply does not execute any code that appears before the foreach loop.

Below is the full method:

    private void pNGToolStripMenuItem_Click(object sender, EventArgs e)
    {
            stat.Text = "Converting to PNG.";
            _piclist.Enabled = false;

            foreach (ListViewItem item in _piclist.Items)
            {
                try
                {
                    /* magical image conversion here. */
                   _piclist.Enabled = true;
                       stat.Text =
                          "Conversion comlpete.";

                }
                catch (Exception exception)
                {
                    stat.Text =
                        exception.Message;

                }
            }
    }

Can somebody please help me understand why the code:

stat.Text = "Converting to PNG.";
            _piclist.Enabled = false;

before the foreach loop never gets executed?

Thanks

+1  A: 

Sounds like you haven't registered the handler with the event... (+=)

Martin

Ps. To clarify - I'm saying that the entire method doesn't get called because I suspect you haven't got this handler registered for the event...

Martin Milan
"But the problem is not that it doesn't do the work in the loop, but it simply does not execute any code that appears before the foreach loop." - The foreach loop does get called. And the event has been registered, but thank you anyway :)
lucifer
Sorry - I thought when you said the lines were not being executed that you would have verified this with a breakpoint...
Martin Milan
+5  A: 

It does. The thing is that body of your loop immediately overwrites the results of code that was run before:

stat.Text = "Converting to PNG.";
            _piclist.Enabled = false;

           _piclist.Enabled = true;
               stat.Text =
                  "Conversion comlpete.";

You don't see it, because UI freezes while your method execute and you see only last changes. Consider using threads, great article here: http://msdn.microsoft.com/en-us/magazine/cc164037.aspx

Andrey
Ah. That kind of explains it. But what I don't understand is that why it overwrites it before the image conversion is complete. There is a good 15 seconds in-between the first status message, and the second one.
lucifer
@j-t-s, if you do long running activities in event handlers (which is bad practice by itself) your UI freezes until the execution leaves method. so the change happen but you can't see it because UI is not updated. Consider using threads.
Andrey
Thanks Andrey! I used to use threads for long-running activities that involved the UI having to update, but stopped because I got sick of people saying crap like: "Why are you using threads for this!!???", which made me assume I was doing something wrong, and since I couldn't backup my reasons for using threads, I had to assume they were right.
lucifer
@j-t-s don't listen to people that suggest or reject some technical decisions without arguments. UI must be responsive and don't freeze. i don't know any other tool than threads (or their derivatives) that can do it.
Andrey
You can call Application.DoEvents() immediately before your loop. That should get the UI to update.
NascarEd
+4  A: 

How did you confirm that the code was never executed? Did you set a breakpoint?

As soon as the foreach loop is entered, the _piclist.Enabled and stat.Text values set before the loop are are overwritten by the new values (to true and "Conversion complete". Probably the user interface is never updated in the mean time.

M4N
I did set a breakpoint, and stepped through the code while debugging, and the first stat.Text never displays. I think you're right in assuming the interface doesn't update. How can I make sure that it updates when I need it to? Or should that be a separate question?
lucifer