msgbox not modal

Mike_etc

Member
Joined
Jun 7, 2020
Messages
7
Programming Experience
10+
I have been writing code in VB for 30+ years up thru VB6. I had not moved to VB.Net as I was close to retirement. I've been retired for more than 10 years now. For the fun of it I decided to improve myself by trying to move to VB.Net. Although I am comfortable with VB I am very much a newbe in VB.Net. I apologize if that shows in the simplicity of a problem I have run into.

I have been trying to re-write a program in VB.Net that works quite well in VB. My VB.Net program requires a text file that meets certain criteria to continue. In the form load event of my main form I use OpenFileDialog to allow the user to select a file. I use an IF Then_Else_End If structure to respond to the 2 dialog buttons. When Cancel is selected, I use MsgBox to offer the user the option of ending the program or selecting a file. If a file is selected I test that the file meets needed criteria. If the file fails the test I use MsgBox to offer the user the option of ending the program or selecting a new file. My problem is this, when I run the code and put in a breakpoint I can successfully step through all of the selection options with all of the message box dialogs properly firing. When I remove the breakpoint and run the code, none of the message boxes fire and the code seems to hang in a loop. I thought MsgBox was modal and the program should stop and wait for a user response when MsgBox is triggered. Any comments as to what may be happeninmg or any suggestions to how to fix the problem would be appreciated. I can provide my code but as I said I can successfully step through the code but I cannot run it automatically.
 
Last edited by a moderator:
As far as I'm aware, any call to MsgBox on the UI thread should produce a modal dialogue. If that's not working for you then I can only assume that it's something specific to your code. Without seeing that code to test it for ourselves, we can't really tell you what the issue might be. I would suggest that you change a few things though, so your current issue may just disappear.

Firstly, while it should work, I would suggest that you don't use MsgBox in VB.NET. If you're going to use .NET then you should use it, which means calling MessageBox.Show rather than MsgBox.

Secondly, the Load event handler of the startup form is the wrong place to do something that may result in the application exiting. That's because the form is going to be displayed at the end of the event handler no matter what, so you may end up with the form flashing on the screen for a moment and then disappearing, which is poor UX. You should either handle the Startup event of the application or the Shown event of the startup form. The former is executed before the startup form is even created and, if you set e.Cancel to True, the application will exit without ever creating it. The latter is executed immediately after the startup form is displayed, so it will be displayed properly and then close properly if you exit the app. You should either display the startup form or not, not have it flash on the screen momentarily.

If you make the appropriate changes and you still have an issue, you should post back with the simplest code possible to demonstrate the issue.
 
As far as I'm aware, any call to MsgBox on the UI thread should produce a modal dialogue. If that's not working for you then I can only assume that it's something specific to your code. Without seeing that code to test it for ourselves, we can't really tell you what the issue might be. I would suggest that you change a few things though, so your current issue may just disappear.

Firstly, while it should work, I would suggest that you don't use MsgBox in VB.NET. If you're going to use .NET then you should use it, which means calling MessageBox.Show rather than MsgBox.

Secondly, the Load event handler of the startup form is the wrong place to do something that may result in the application exiting. That's because the form is going to be displayed at the end of the event handler no matter what, so you may end up with the form flashing on the screen for a moment and then disappearing, which is poor UX. You should either handle the Startup event of the application or the Shown event of the startup form. The former is executed before the startup form is even created and, if you set e.Cancel to True, the application will exit without ever creating it. The latter is executed immediately after the startup form is displayed, so it will be displayed properly and then close properly if you exit the app. You should either display the startup form or not, not have it flash on the screen momentarily.

If you make the appropriate changes and you still have an issue, you should post back with the simplest code possible to demonstrate the issue.
Thank you for your comments. As I said I am new to VB.Net. I am working on my first project and I thought it would be easier to take a program that I successfully wrote in VB6 and attempt to re-write it in VB.Net. I am in the early stages of that re-write. My VB6 code loaded a database into a grid during the form load. The name and location of the database was fixed in the code. I was uncomfortable with the program requiring the database to be in a fixed location and in re-writing the code I fell into the trap of trying to do two things at once. Instead of specifying a fixed name and location for the database in the form load event I was merely trying to give the user the option of selecting a file of any name from any location. In then trying to protect the user I was building in certain tests and messages regarding those tests. I was having difficulty writing the code in VB.Net to respond to user actions from MessageBox so I fell beck on using MsgBox from VB, which is where I ran into the problem I raised in the community. Old habits are hard to change and you are right in that if I’m going to learn VB.Net I should do so all the way.



You are also absolutely right in your comments that I had not (yet) considered the appearance of the program. To solve that problem first, I have removed the code to select a database, open the file and load the data into a grid (actually a subroutine call) from the form load event and am allowing the form to load with an empty data display grid. This necessitated disabling all of the data manipulation menu items and command buttons. These will then be enabled when a valid data file is opened and loaded into the grid. I have then added a File|Open menu command that now calls the subroutine that had been called during the form load event. A further comment as to appearance, my VB6 code actually loads a splash screen for a period of a few seconds before then calling for the load of the main program form. This splash screen is also opened with the Help|About menu command



I will now return to the subroutine allowing the user to select the data file to open and I will work on trying to use MessageBox instead of MsgBox. Thank you again for your comments. I know I have much to learn about VB.Net
 
Quick follow-up. Once the main form is loaded and I use File|Open menu command to run my file selection and test codes, MsgBox fires as expected. Apparently VB.Net doesn't like modal forms displayed during a form load event.
 
The MsgBox runtime function calls MessageBox.Show internally too. There is no problem showing a dialog in Load event that I can see.

Splash screen can be set in project properties window.
 
Form Load event is not the right event to be placing code for poping dialogs. This event is for performing actions before the form is displayed. As described in the docs. I'm not sure why you would want to be popping message boxes or any other dialog before the window is first shown.

In the form load event of my main form I use OpenFileDialog to allow the user to select a file.

There for Form.Shown Event (System.Windows.Forms) Would be a better event in my opinion. Placing code in the load event has been known to cause problems in some cases, although most people use it anyway because there are not enough people correcting people about what the Load Event is actually for.
 
The MsgBox runtime function calls MessageBox.Show internally too. There is no problem showing a dialog in Load event that I can see.

Splash screen can be set in project properties window.
I made a few changes while moving my RetrieveFile routine out of the main form load event so I wanted to make sure it still failed when called from within the form load before I responded. It still fails. Finding out why it failed is more of a curiosity now than a necessity since the call works after the form is loaded when called fro the File|Open menu command. However, attached is my RetrieveFile code including the code for called subroutines/functions.

 

Attachments

  • Code.txt
    2.9 KB · Views: 22
Sleeping,
I am curious and willing to learn. This is the first I have heard of any objection to using the form load event. The problem raised in my initial post may very well be an example that proves your point. Can you expand a bit on how you see the form load event being used. In many of the programs I have written I have used the form load event to execute code that should only be executed once. If this same code were placed in the form shown event would it not be executed the first time the form is displayed and then every time the form were hidden to display a new form (such as an options form) When finished with the new form and the original form were revealed would this not trigger the form shown event thus executing the one-time code again?
 
In many of the programs I have written I have used the form load event to execute code that should only be executed once. If this same code were placed in the form shown event would it not be executed the first time the form is displayed and then every time the form were hidden to display a new form (such as an options form) When finished with the new form and the original form were revealed would this not trigger the form shown event thus executing the one-time code again?
You are confusing events. Load is raised immediately before the form is displayed for the first time and Shown is raised immediately after the form is displayed for the first time. I disagree with Sheepings. In early versions of Windows Forms, there was no Shown. There was a Load event and that is where you were intended to execute any code that you wanted to occur when the form loaded. You can also add code to the constructor but that should be only for actual construction. If you want to prompt the user for a file path and use that file path when you load a form then there's nothing wrong with using the Load event. Load was fine for most scenarios but there were rare cases where you needed the form to be visible before executing code. In such cases you originally had to handle the `Activated` event and manually filter for the first instance. That was an unnecessary pain and thus the Shown event was added. Load should be your first option and Shown should be used only if you specifically want/need the form to be displayed before executing your code.

In this case, Load is not appropriate because you don't want to display the form at all under certain circumstances. Like I said, handling the Startup event of the application allows you to prevent creation or display of any forms at all. If you are going to create and display the startup form then it will/may momentarily flash on the screen the way you're using it. In that case, Shown would be preferable because at least the form would be displayed properly. The problem may be that displaying the form without a file having been selected may cause issues.

I almost forgot to mention, the behaviour that you are suggesting might result form Shown is actually what you would see from VisibleChanged and/or Activated.
 
Placing code in the load event has been known to cause problems in some cases
As far as I'm aware, the problems relate to the fact that exceptions can be swallowed when thrown in the Load event handler. This is not a reflection of what that event is or is not for. My understanding is that it was due to some incompatibility between .NET and 64-bit Windows that each team blamed on the other and was thus not addressed by either. The solution was to add a Try...Catch block to the event handler. I believe that it is no longer a problem in Windows 10, although I'm not sure exactly when it was addressed. Again, this is not the result of people using the Load event incorrectly.
 
As far as I'm aware, the problems relate to the fact that exceptions can be swallowed when thrown in the Load event handler.
This still happens today. So you are right that it has never been fixed.
I believe that it is no longer a problem in Windows 10, although I'm not sure exactly when it was addressed.
I wasn't aware it was fixed and I was of the belief that its still an ongoing issue. As you know Microsoft are slow to make fixes, since Windows has more holes in it than an Ants nest.

I also didn't write the Microsoft developer network documentation. I just follow it as its written. So just because everyone else on the internet tells you to use the form load event. That doesn't make it right to do so, just because everyone else does. Microsoft expresses that the Shown event should be used when the form is fully shown; when you want to do things with the controls of said form. The only time I use the Load event is if I am trying to initialize something before the form is shown.

The swallowing of errors in the load event is still an issue as far as i am aware. But don't hold me to that re- windows 10 until you check the error report has addressed a fix.
 
I also didn't write the Microsoft developer network documentation. I just follow it as its written. So just because everyone else on the internet tells you to use the form load event. That doesn't make it right to do so, just because everyone else does. Microsoft expresses that the Shown event should be used when the form is fully shown; when you want to do things with the controls of said form. The only time I use the Load event is if I am trying to initialize something before the form is shown.
Given that Load has existed since .NET 1.0 and Shown was introduced in .NET 2.0, it would seem odd that they wanted people to use Load originally and then changed their mind and wanted them to use Shown. It's not beyond the realms of possibility but it would seem odd. When I was working with .NET 1.1, there were a few times that I specifically needed to do something after the form was displayed rather than before and, in those cases, I had to handle the Activated event and use a flag to filter for the first instance. As far as I can tell, the Shown event was added specifically for those situations. All the situations that used the Load event before would still use the Load event.

To me, it comes down to the fact that you'd generally like to have your form fully initialised before displaying it to the user. Having it displayed in one state and then change to another for no apparent reason is not great UX. You'd have to look at each scenario individually to determine what was best in any particular case but that's the reason that, for me, Load should be the default.
 
jmcilhinney,
Thank you for your explanation of the difference between the Shown event and VisibleChanged and/or Activated events. I have used the latter in some VB6 programs but up until now was not familiar with how the Shown event behaves. I do not have a problem with my form showing an empty grid. I have solved my problem by letting the form load without specifying a data source, showing an empty grid, and then disabling all data manipulation actions until a valid data source is selected via File|Open menu command
 
Back
Top