tags:

views:

61

answers:

2

I have this situation. Application.OpenForms doesnt return the right result. ie Application.OpenForms.Count = 0 always..

Purpose of getting the form is get the owner of the Form so that I can pass the owner as the parameter of the MessageBox.Show() function.

A: 

To reproduce the problem, i have done like following, and it shown me '2' in the message box, which is correct.

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Form f1 = new Form();
            f1.Show();
            Form f2 = new Form();
            f2.Show();
            MessageBox.Show(Application.OpenForms.Count.ToString());
        }
    }

If this is not you are looking for, then can you please explain your scenario, like on which event you are trying to access the property etc. details?

EDIT:

If you are using MDI forms then, you can get the count like following :

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.IsMdiContainer = true;

            Form f1 = new Form();
            f1.MdiParent = this;
            f1.Text = "F1";

            Form f2 = new Form();
            f2.MdiParent = this;
            f2.Text = "F2";

            f1.Show();
            f2.Show();
            //MessageBox.Show(Application.OpenForms.Count.ToString()); //If uncommented, this line give you count as '0'
            MessageBox.Show(this.MdiChildren.Count().ToString());
        }
    }
Siva Gopal
This doesn't answer the question.
Hans Passant
+4  A: 

There's a bug in Windows Forms that makes a form disappear from the Application.OpenForms collection. This will happen when you assign the ShowInTaskbar, FormBorderStyle, Min/MaximizedBox, RightToLeftLayout, HelpButton, Opacity, TransparencyKey, ShowIcon or MdiParent property after the window was created. These properties are special in that they are specified as style flags in the native CreateWindowEx() call. This sample form demonstrates the bug:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        button1.Click += button1_Click;
    }
    private void button1_Click(object sender, EventArgs e) {
        Console.WriteLine(Application.OpenForms.Count);
        this.ShowInTaskbar = !this.ShowInTaskbar;
        Console.WriteLine(Application.OpenForms.Count);
    }
}

Windows Forms must re-create the window the apply the changed property. That has side effects beyond the very noticeable flicker, one of them is that the Application class loses track of the form. Avoid the bug by setting the property only in the constructor, never in any event handlers.

In general, avoid relying on OpenForms due to this bug. Give the class that needs to display the message box a reference to the form instance through its constructor. MessageBox usually figures out a parent window by itself correctly btw.

Hans Passant
MessageBox uses the Win32 API method GetActiveWindow which can return a window that doesn't belong to your app. It's better not to rely on this and always specify the owner window yourself.
Tergiver
@Tergiver: GetActiveWindow can only return a window handle for a window that was created on the same thread. http://msdn.microsoft.com/en-us/library/ms646292%28VS.85%29.aspx
Hans Passant
@Hans: You are correct. I apologize, I seem to be getting my API methods confused.
Tergiver