代码之家  ›  专栏  ›  技术社区  ›  Davide Vitali

取消表单关闭

  •  1
  • Davide Vitali  · 技术社区  · 7 年前

    我正在编写WinForm桌面应用程序。在主窗体中,用户单击一个按钮,该按钮调用另一个窗体供用户向其提交数据。在此提交过程结束时,用户单击“保存”菜单项以关闭子窗体。

    以下是子窗体调用的代码:

    private void btnSubmit_Click(object sender, EventArgs e)
    {
        // code for setting myFormArgs
    
        myForm form = new myForm(myFormArgs);
        form.ShowDialog();
    
        // the user clicked "Yes" on a "Confirm" MessageBox
        if (form.DialogResult == DialogResult.Yes)
        {
            // code for saving data 
    
            form.Dispose();
        }
    }
    

    这是子窗体中“保存”菜单项的代码:

    private void menuSave_Click(object sender, EventArgs e)
    {
        string message, title;
        MessageBoxIcon icon;
        MessageBoxButtons buttons;
    
        if(DataSubmitted)
        {
            if(ValidData)
            {
                message = "Confirm?";
                title = "Select an action";
                icon = MessageBoxIcon.Information;
                buttons = MessageBoxButtons.YesNo;
            }
            else
            {
                message = "Incomplete data";
                title = "Error";
                icon = MessageBoxIcon.Error;
                buttons = MessageBoxButtons.OK;
            }
        }
        else
        {
            message = "No data submitted";
            title = "Error";
            icon = MessageBoxIcon.Error;
            buttons = MessageBoxButtons.OK;
        }
        this.DialogResult = MessageBox.Show(message, title, buttons, icon);
        if (this.DialogResult == DialogResult.Yes) this.Close();
        else this.OnFormClosing(new FormClosingEventArgs(CloseReason.None, true));
    }
    

    问题是代码总是返回到调用方法,因此关闭(可能只是隐藏?)子窗体,即使 this.Close() 未调用方法。

    提前谢谢。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Dor Lugasi    7 年前

    您不应该创建新的事件实例,这些是您希望避免的事情 相反,请尝试:

    DialogResult dialogResult = MessageBox.Show("Sure", "Some Title", 
    MessageBoxButtons.YesNo);
    if(dialogResult == DialogResult.Yes)
    {
        Close();
    }
    

    事件应该自动发生,因此当表单关闭时,“OnFormClosing”将引发。

    我也建议使用这个。关闭而不是处置 类型Close()发送正确的Windows消息以关闭win32窗口。在此过程中,如果表单未以模式显示,则会对表单调用Dispose。处理表单会释放表单所持有的非托管资源。

    对于更有组织的代码, 尝试从主窗体创建窗体实例 并按如下方式处理对话框结果:

    using (SubForm form = new SubForm())
    {
         DialogResult dr = form.ShowDialog();
             if(dr == DialogResult.Yes)
             {
                 string studdToSave= form.StuffToSave;
                 SaveToFile(studdToSave);
             }
    
    }
    
        2
  •  0
  •   Frederik Gheysels    7 年前

    我觉得奇怪的是,当用户只想保存数据时,您却想关闭表单。:)

    保存时不应关闭表单。

    关闭表单时,应验证是否有未保存的更改。 如果有,请询问用户是否要在关闭前保存更改,并向其提供选项Yes、No和Cancel,其中Cancel表示“取消关闭表单”。

    根据用户单击的是或否,您应该或不应该保存更改。 如果用户单击了“取消”,则应通过为FormClosing事件创建一个事件来取消关闭表单。此事件允许您取消关闭表单。

        private void btnClose_Click(object sender, EventArgs e)
        {
            if (unsavedChanges)
            {
                var result = MessageBox.Show("Save changes?", "unsaved changes", MessageBoxButtons.YesNoCancel);
    
                if (result == DialogResult.Yes)
                {
                    SaveChanges();
                }
                if (result == DialogResult.Cancel)
                {
                    cancelClose = true;
                }
                this.Close();
            }
        }
    
        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = cancelClose;
            cancelClose = false;
        }
    

    当“Form2”不是模态形式时,上面的代码很有用。

    如果您希望Form2显示为模态,那么上面的代码也可以使用。但是,在这种情况下,也可以使用窗体的DialogResult属性:

        private void btnClose_Click(object sender, EventArgs e)
        {
            if (unsavedChanges)
            {
                var result = MessageBox.Show("Save changes?", "unsaved changes", MessageBoxButtons.YesNoCancel);
    
                if (result == DialogResult.Yes)
                {
                    SaveChanges();
                }
    
                if (result == DialogResult.Cancel)
                {
                    result = DialogResult.None;
                }
    
                this.DialogResult = result;
            }
        }