通知Modal表示需要采取行动的父母

时间:2011-11-15 10:41:42

标签: c# .net winforms events modal-dialog

我有一个父表单打开一个模态表单,它基本上允许用户更改应用程序的数据库设置。

当用户单击模态(子)窗体上的保存按钮时,它会使用新设置保存Settings对象,但我需要让Main窗体检查数据库设置是否正确。

我目前通过一个尝试简单连接到数据库的函数来执行此操作,如果成功则返回true,如果失败则返回false。该函数我在应用程序构造函数中执行,因此只要应用程序关闭并重新启动它就可以正常运行。

我在保存设置后在模态窗体中尝试了以下内容,但是为对象myManager获取了NullReference异常。

这是获取新设置并保存它们的函数,然后尝试调用父窗体CheckDatabaseIsSetup()公共函数来测试数据库连接。

/// <summary>
    /// Save the settings and then hide the Settings window
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btn_Save_Click(object sender, EventArgs e)
    {            
        // TRUE: User indicates that we are to connect using a trusted connection
        // FALSE: User wants to use Integrated security to connect.
        if (rb_UseTrustedConnection.Checked)
        {

            AppSettings.DatabaseName = tb_Trusted_DbName.Text;
            AppSettings.Server = tb_Trusted_Server.Text;
            AppSettings.UseIntergratedSecurity = false;
        }
        else
        {
            AppSettings.DatabaseName = tb_Secure_DbName.Text;
            AppSettings.Server = tb_Secure_Server.Text;
            AppSettings.Username = tb_Secure_Username.Text;
            AppSettings.Password = tb_Secure_Password.Text;
            AppSettings.UseIntergratedSecurity = true;
        }

        try
        {             
            AppSettings.SaveSettings();
            BushBreaksLodgeManagerMain myManager = (BushBreaksLodgeManagerMain)this.ParentForm;
            myManager.CheckDatabaseIsSetup();
        }
        catch (Exception ex)
        {
            log.LogAppendWithException(ex);
        }

        this.Hide();
    }

4 个答案:

答案 0 :(得分:1)

最好以子格式定义事件并以主窗体处理此事件 当你以子形式提出这个事件时,mainform可以做自己的工作

答案 1 :(得分:1)

BushBreaksLodgeManagerMain myManager = (BushBreaksLodgeManagerMain)this.ParentForm;

您可以查看上面的行,ParentForm是否属于/可以转换为BushBreaksLodgeManagerMain。我认为案件不成功因此返回null

答案 2 :(得分:1)

我通常通过使用我的Emesary库提供的对象互通来实现这一点;设计是以这样一种方式使用通知,即请求由知道它需要处理这些通知的任何事件发送和处理,例如,很容易添加到断开连接的额外事件处理程序。

在这种情况下,检查数据库设置的代码将变为:

if (ReceiptStatus.OK == 
    GlobalNotifier.NotifyAll(new CheckDatabaseIsSetupNotification(tb_Secure_DbName.Text,
                             tb_Secure_Server.Text,
                             tb_Secure_Username.Text,
                             tb_Secure_Password.Text,
                             true))
{
     // do something.
}

要完成这项工作,您需要在BushBreaksLodgeManagerMain和构造函数调用中实现IReceiver

    GlobalTransmitter.Register(this);

然后实现接口接收:

public ReceiptStatus Receive(INotification _message)
{
    if (_message is CheckDatabaseIsSetupNotification)
    {
         var message = _message as CheckDatabaseIsSetupNotification;
         if (connect_to(message.DatabaseName, message.Server, Message.Username, message.Password, message.UseIntergratedSecurity))
            return ReceiptStatus.OK;
         else
            return ReceiptStatus.Fail;
    }
    return ReceiptStatus.NotProcessed;
}

您可以使用Windows事件执行此操作 - 但这种方式更清晰,并允许与不一定具有窗口的对象进行互操作。

答案 3 :(得分:1)

您应该使用模式形式的Owner属性而不是ParentForm属性,如下所示:

BushBreaksLodgeManagerMain myManager = (BushBreaksLodgeManagerMain)this.Owner;

Owner属性定义了拥有(模态)表单和父(所有者)表单之间的实际关系。