开发者

c# cancel application from closing if hidden form has unsaved changes

开发者 https://www.devze.com 2023-02-13 16:48 出处:网络
after searching google and stackoverflow I\'m unable to find an answer that helped me in my situation. I\'ve got an application with a start menu(form). when the user presses the X(close) of a (any) f

after searching google and stackoverflow I'm unable to find an answer that helped me in my situation. I've got an application with a start menu(form). when the user presses the X(close) of a (any) form I reload the start menu. Now when that(menu) form gets closed I want to check and notify the user wheter any now hidden forms are in editing mode (with or without unsaved changes) if user presses cancel I want to show that form and stop the application from closing. Now my problem is how do i stop the application from stopping in the code of the other forms. I have an override of the dispose method of the subforms that calls this.close so the ok/cancel messagebox shows but after the MB the start menu closes anyway stopping the program. Should I look for a different method of handling these things or is there a method or eventhandler to modify so this /\ can work?

EDIT: ok here's parts of the code in order of being called. Where does i go wrong?

private void Menu_FormClosing(object sender, FormClosingEventArgs e)
    {
       Global.Forms.Remove(this);
        if (!Global.Clean_Forms())
        {
            e.Cancel = true;
            Global.Forms.Add(this);
        }
    }

public static void Clean_Forms()
    {


        foreach (Form f in Forms)
            {
                if (f is Menu)
                {
                    //do nothing
                }
                else
                {
                    if (!f.IsDisposed)
                    {


                        f.Close();
                    }

                }

            }
        if (Forms.Count != 0)
        {
            isClean = false;
           /* String a = "";
            foreach (Form f in Forms)
            {
                a += f.ToString() + ": ";
            }
            MessageBox.Show(a);*/
        }
        else
        {
            isClean = true;
        }

    }

Yet this doesnt work, application just closes down.

the closing event handler of random form

private void persoon_form_FormClosing(object sender, FormClosingEventArgs e)
    {

        if (editing)
        {
            DialogResult dr;
            dr = MessageBox.Show("uw wijzigingen gaan verloren. Doorgaan?", "sluiten", MessageBoxButtons.OKCancel);
            if (dr == DialogResult.Cancel)
            {
                e.Cancel = true;


            }
            else if (dr == DialogResult.OK)
            {
                Global.size = this.Size;
                Global.position = this.Location;
                Global.Forms.Remove(this);
                Form f = Global.menu();
    开发者_JAVA百科            f.Show();
                this.Dispose();
            }
        }//somethingelse}

EDIT: @cody gray changed onclose and clean_form still no effect, (shouldn't the messagebox in the Closing event of the subform be shown anyway? cause it doesnt)


You should not be doing this in the Dispose method. Instead, try handling the FormClosing event.

This event occurs before the form is closed, so you can check whatever state you need to, and cancel the close if necessary by setting e.Cancel to True.

For example:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    base.OnFormClosing(e);

    // Check to see if the user is allowed to close this form
    if (!allowClose)
    {
       // Prevent this form from being closed
       MessageBox.Show("This form cannot be closed yet!");
       e.Cancel = true;
    }
}


I think i figured it out! I changed two things. 1 I made sure that I didn't call this.dispose anywhere as that will result in disposing (not closing) any child forms hence no onclosing event is called. 2. the foreach loop when checking if main menu can close generated collection was modified errors. so with this I made sure it closes in the right order thnx Cody Gray for pointing me in the right direction:

Stack<Form> stack = new Stack<Form>();
            foreach (Form f in Forms)
            {
                if (f is Menu)
                {
                    //do nothing
                }
                else
                {
                    if (!f.IsDisposed)
                    {


                        stack.Push(f);
                    }

                }

            }
            for (int i = 0; i < stack.Count; i++)
            {
                Form temp = stack.Pop();
                temp.Close();
            }
0

精彩评论

暂无评论...
验证码 换一张
取 消