Link to home
Start Free TrialLog in
Avatar of MrSlausen
MrSlausen

asked on

UI won't respond until entire code block executes

I have an Excel 2007 VSTO add-in that I am having difficultly getting the UI to respond quickly enough.  In the code, you will see a button click event that disables the button.  This is to prevent the user from clicking the button again.  Below in the procedure, I am spinning off another thread and doing a whole bunch of stuff, and the UI doesn't update until the procedure is finished executing.

That is causing major issues.  I thought the DoEvents() method would work, but it didn't.  I need to know how I can force the UI to refresh itself and disabled the button before proceeding. The code is generally a test sample to illustrate that I'm not getting the UI in time.

Any thoughts?  
private void button1_Click(object sender, RibbonControlEventArgs e)
        {
            if (button1.Enabled)
            { button1.Enabled = false; }
            else
            { button1.Enabled = true; }

            System.Threading.Thread.Sleep(4000);
            Application.DoEvents();
            System.Threading.Thread.Sleep(4000);
            // The UI button doesn't show as disabled until the code gets to here.  How can I change that?
}

Open in new window

Avatar of AnilKumarSharma
AnilKumarSharma
Flag of India image

Better to do the else part in a worker thread, if other operation can be performed that are not dependent upon the else part working or outcome.

For this you may need to add some mechanism like say a flag that enabled when executing else part. This flag will be checked for any operation that depend upon else part. Such case either just not allow that operation or inform user about working process. The working background thread can contain/send event about its state of processing in between that help to update the user for its status and can also allow user to interrupt that process in between.

hth
Avatar of MrSlausen
MrSlausen

ASKER

I agree about adding a flag, but I also did that to no avail.  I'm not so concerned about making this the best practice of getting the threading just perfect. I am most concerned with the UI lag issue.  As soon as the button is clicked, it needs to be disabled.  Regardless of what I do afterwards, the button needs to be disabled prior to moving on.

How do I do that?
try to call after setting button state, but before other code :-
 Refresh();
Basically whenever you change a UI-visible property of a control, such as Enabled, you want to make sure and force the UI to update with a call to Control.Refresh() before you implement other functionality.

HTH

Avatar of Mike Tomlinson
"As soon as the button is clicked, it needs to be disabled."

Move "Application.DoEvents();" to immediately after you disable the button and BEFORE the call to Sleep().
SOLUTION
Avatar of Naman Goel
Naman Goel
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks everyone for your feedback.  "naman_goel", I appreciate the explanation.  I didn't realize DoEvents() had so many implications.  I'll keep that in mind.

Regarding the issue, the button on an Excel 2007 ribbon does not operate like a standard WinForms button.  For one, there is no Refresh() method.  Secondly, I can't get the ribbon to refresh until all the code is done.  I have no difficulty with this functionality in a WinForms.  It is in the Excel ribbon that I have issues.  Try it out.  You'll see that it doesn't work the way you would expect.  

I'm looking for the workaround for this.

Thanks!
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
even I agreed with tgerbert.
Thanks for the responses!  I won't be able to check this for a day or two, but I'll definitely respond once I have a chance.

Thanks,

Mark
I have closed this thread.  The resolution was generally from tgerbert, but I really appreciated the commentary by nomen_goel as well.  

In the end, my architecture was poor.  I wasn't handled the work in an efficient manner.  I had time-consuming operations in the main thread and some in another thread, and it was just poor design.  Reworking the code was the answer using the example given by tgerbert.

Thanks everyone!