1

I have a winforms single form application that uses a "Thickbox" I've created whenever the loads a new view into the application form.
The "Thickbox" shows another form in front of the application's form that is semi-transparent and has a user control that is the box itself.

This thickbox can be shown a modal dialog and in that case I have no problems at all, but it can also be shown as a non modal, for instance, when the user switches views in the main form, it shows thickbox with a loading animated icon.

The problem is that when the thickbox is shown as non modal, it doesn't block the user from clicking on the buttons of main form of the application.
When thickbox is shown nothing happens, but as soon as it's closed, the click is being processed by the click event handler of the relevant button in the main form.

I can't use ShowDialog since I can't block the UI thread, and I need to get the indication from the main form when to close the thickbox,
I can't set the Enabled property of the owner form as described in this answer (though I've tried various versions of this solution, nothing helps)
I've tried using the win API function BlockInput as descried in this answer, but that didn't block the input,
I think my best chance is using the Application.FilterMessage method, but I couldn't get that to block the mouse clicks as well.

It would be great if I could encapsulate the mouse click blocking inside the thickbox form itself, so that it would be usable easily with other applications as well, but a solution on to the calling form would also be very much appreciated.

Community
  • 1
  • 1
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • Wait, why can't you set the `Enabled` property of the owner form? That would have been my recommendation after reading the question, and you don't explain here why it doesn't work. That is essentially what a modal dialog is doing, and should be exactly the behavior you want. – Cody Gray - on strike Feb 28 '16 at 16:24
  • @CodyGray: That was my initial though also, and I did try to do that, but there are 2 problems with this option in my case: the first one is that it delays the appearance of the loading icon, the second one is that it changes the colors of most of my buttons in the main form and doesn't change them back fast enough after closing the thickbox. I've tried to do it in the form_shown, in the userControl's load, even in the userControl's paint event, but nothing was good enough... – Zohar Peled Feb 28 '16 at 16:33
  • I don't know why it would delay the appearance of the icon. I'm not really even sure what that means without seeing your code. My guess would be that disabling the form stops your loading code. As far as changing the colors of your buttons, that makes sense, because it disables those buttons, and disabled buttons obviously look different. If you re-enable the parent form *before* closing the pop-up dialog, then the buttons should update by the time the pop-up dialog is closed. If not, you can force them to redraw themselves by invalidating the form. So both of these are code-ordering issues. – Cody Gray - on strike Feb 28 '16 at 16:37
  • @CodyGray Believe me I've tried that as well... I even tried using async tasks for that, but nothing seems to do the job good enough... – Zohar Peled Feb 28 '16 at 16:39
  • The real crazy part is that I've now tried to replicate the issue with a new winforms application and It seems to be working fine with the new application. – Zohar Peled Feb 28 '16 at 16:42
  • I'm not surprised. It is the solution that every other app out there uses. :-) If you can get enough of the code from your app together to reproduce the problem, you have a good question on your hands. – Cody Gray - on strike Feb 28 '16 at 16:44
  • @CodyGray Thanks, I'll start to load the test application with the code from the original application and hopefully see when it starts to misbehave.... – Zohar Peled Feb 28 '16 at 16:46

1 Answers1

0

I'm glad to announce that the problem is finally solved.
After spending a few days attempting to recreate this bug in a new application, re-constructing the main form in the application, comment out parts of the code in the main application, and generally just shooting all over to try and find a lead, It finally hit me.
The application behaved as if the clicks on the thickbox was queued somehow and only activated when the thickbox was closed. This morning, after fixing some other bugs, The penny finally dropped - all I was missing was a single line of code right before closing the thickbox's form:

Application.DoEvents();

The annoying thing is that it's not something that's new to me, I've used it many times before including in the main application and in the thickbox code itself... I guess I just had to let if go for a while to enable my mind to understand what was so painfully obvious in hindsight...

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121