1

I'm writing an application where the main form has to be hidden, but it shows a dialogue when it starts up.

My main form has the following line in an initialize() method that is called by the constructor.

this.Load += new System.EventHandler(this.MainForm_Load);

I've verified that the code above it hit But the MainForm_Load() method is never called.

Could this be because I am hiding the form?

I execute the following line in the Main of Program.cs:

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

And have overridden the following method in the Form:

protected override void SetVisibleCore(bool value)
{
    _logger.Debug("Hiding the main window");
    base.SetVisibleCore(allowShowDisplay ? value : allowShowDisplay);
}

Where allowShowDisplay is set to false;

I found at least part of this solution in the answer to this queston and have used it in another project. That project didn't use the form load event though. The one I'm working on does.

UPDATE This is what the Main method looks like. I'm trying to inject the dependancies into the all the elements. I've changed the names to remove customer names.

[STAThread] static void Main() {

        ServiceHost incomingPipeHost = new ServiceHost(typeof(ScreenPopService));
        incomingPipeHost.Open();

        XmlConfigurator.Configure();
        _logger.Debug("Starting Application");
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        _logger.Debug("Creating subformView"); 
        ISubformView subformView = new SubformView();

        _logger.Debug("Creating MainForm mainForm");
        MainForm mainForm = new MainForm();

        _logger.Debug("Creating MonitorController");
        IMonitorController MonitorController = new MonitorController();

        _logger.Debug("Adding View to MonitorController");
        MonitorController.View = mainForm;

        _logger.Debug("Adding subFormView to mainForm");
        mainForm.SubFormView = subFormView;

        _logger.Debug("Adding MonitorController to mainForm");
        mainForm.MonitorController = MonitorController;

        _logger.Debug("Loading Properties");
        IProperties properties = PropertiesManager.LoadProperties();

        _logger.DebugFormat("Loaded Properties [{0}]", properties);
        _logger.Debug("Setting properties on mainForm");
        mainForm.Properties = properties;

        _logger.Debug("Setting properties on MonitorController");
        MonitorController.Properties = properties;

        _logger.Debug("Settting ScreenPop Consumer on MonitorCotroller");
        MonitorController.screenPopConsumer = ScreenPopCallBackManager.Instance;

        _logger.Debug("Debug Running Application");

        Application.Run(mainForm);
    }
Community
  • 1
  • 1
Omar Kooheji
  • 54,530
  • 68
  • 182
  • 238
  • are you creating an Instance of the new form..? if so show the code that applies to the question / issue at hand.. – MethodMan Aug 03 '12 at 14:50
  • I'm creating an instance of the form adding a bunch of parameters to it and then calling Application.Run with the form as a parameter. The form also has a notification icon associated with it which is displaying. – Omar Kooheji Aug 03 '12 at 14:53
  • The example I posted I have working but not sure if it's something you are looking for.. notice how I create an Instance of the form.. you could do the same and Override / set values that way as well.. – MethodMan Aug 03 '12 at 14:59
  • I didn't realize that you are doing so much logic prior to the main form being visible.. I need to look at your code again because I posted my Answer prior to you pasting / editing all the new Code.. give me a few minutes to look over it – MethodMan Aug 03 '12 at 15:02
  • Rather than handle the Load event, it would be better to just override the OnLoad method. – Chris Dunaway Aug 03 '12 at 15:08
  • I don't see a mainForm.Show() anywhere in your code.. also you could move all that code into the OnLoad Method of the mainForm, and call mainForm.Show() as your last command ... – MethodMan Aug 03 '12 at 15:10
  • I don't want to show the main form to show that is the problem. When I remove the override of SetVisibleCore The main form shows but everything works. With it main form doesn't show but OnLoad and MainForm_Load don't execute. – Omar Kooheji Aug 03 '12 at 15:49

4 Answers4

4

This is by design. The form's Visible property (and the associated SetVisibleCore and Show methods) are a Big Deal in Winforms. In typical .NET lazy fashion, that's what gets the concrete window created. Or in other words, Winforms doesn't create the window unless it has to.

By overriding SetVisibleCore() and forcing the value property to false, you stop this from happening. The window does not get created. And a bunch of other stuff doesn't happen, including firing the Load event. And calling the form's Close() method won't stop the program like it normally does.

This is all normal behavior. If your Load event handler contains important stuff then be sure to move it to the constructor instead. You only really ever need Load to know the size and location of the window.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

I am posting this as how I would do using MDI now inside my Program.cs file this is what my code looks like..

static class Program

{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        try
        {
            Application.Run(new MainForm());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message + "\n\n\n" + ex.GetType().ToString(), "Error in MainForm");

        }
    }
}

now the code in the form that I want to hide then show would have the following code in my MainForm This would be an example of what I am doing if a form loads and I use a menu click event for example. but MDI is what you would want to look at.. change the example to work for your use case.

    private void newStudentRecordToolStripMenuItem_Click(object sender, EventArgs e)
    {
        try
        {
            StudentForm studForm = new StudentForm();
            studForm.MdiParent = this;
            studForm.Show();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message + "\n\n\n" + ex.GetType().ToString(), "Error in Student Form");
        }
    }
MethodMan
  • 18,625
  • 6
  • 34
  • 52
  • Surely it shouldn't matter how I initialize the main form (on a line by it's self or in the Application.Run() method. I'm Still calling Application.Run() – Omar Kooheji Aug 03 '12 at 15:05
  • Omar.. look at my MDI Example Calling Application.Run with a single form I would agree with your statement.. but using multiple forms your assumption is slightly off.. – MethodMan Aug 03 '12 at 15:11
  • I'm not opening up my sub forms using MDI I'm opening them using ShowDialog becuase I care more about the DialogResponse than I do about the form. I think you might be trying to solve a different problem to what I am seeing. – Omar Kooheji Aug 03 '12 at 15:42
0

I can suggest re check the method signatures of MainForm_Load. The signatures should look like "MainForm_Load(object sender, System.EventArgs e)"

This might sound lame, but i have had such problems eat up time :)

Let me know if this helps. Thanks!

Bull
  • 701
  • 1
  • 6
  • 13
  • The mainform_load method was added by the IDE and I didn't edit the signature. I just double checked it and it is correct. – Omar Kooheji Aug 03 '12 at 15:40
0

The solution that I ended up going for that seems to have worked is removing the mainForm from the call to Application.Run() and calling mainForm.show() followed immediately by mainForm.Hide() before the call to Application.Run()

mainForm.Show();
mainForm.Hide();

Application.Run();

Seems to be working.

Omar Kooheji
  • 54,530
  • 68
  • 182
  • 238