0

我有两种形式和 1 个单例类。我正在初始化 formA 的 btn_A_Click 中的单例类。

public partial class frmA : Form
{
    public frmA()
    {
        InitializeComponent();
        frmB frmB;
    }

    private void btn_A_Click(object sender, EventArgs e)
    {
        SessionMgmt.GetInstance().StartFormB(); 
    }
}

这是我的单例类,在这里我尝试使用 Forms.Invoke() 方法。

public class SessionMgmt
{
    static SessionMgmt _sessinMgr;
    frmB frB;

    private SessionMgmt()
    {
        frB = new frmB();
    }

    public static SessionMgmt GetInstance()
    {
        if (_sessinMgr != null)
            return _sessinMgr;
        else
        {
            _sessinMgr = new SessionMgmt();
            return _sessinMgr;
        }
    }

    public bool StartFormB()
    {
        frB.Invoke(new EventHandler(DisplayFrmB));
        return true;
    }

    private void DisplayFrmB(Object o, EventArgs e)
    {
        frB.Visible = true;
        frB.Refresh();
    }

}

这是我的表格B。

public partial class frmB : Form
{
}

但是从frB.Invoke(new EventHandler(DisplayFrmB));方法中它抛出了以下异常:

在创建窗口句柄之前,不能对控件调用 Invoke 或 BeginInvoke。

我无法弄清楚这个问题,如果我错过了什么,请帮助或建议我。

编辑

以下结构是我当前项目显示下一个表单的方式。它是由 VB.NET 完成的,我需要在使用 C# 的新项目中使用类似的东西。我看到了 Invoke 函数,它指向一个事件,然后指向一个函数。在该函数中,它只是使 Form.Visible=true 和 Form.Refresh。但为了理解,我只是尝试了一个 POc 并遵循相同的步骤,但尚未解决。

4

4 回答 4

2

调用调用的原因是什么?这不是为你工作吗?

public bool StartFormB()
{
    frB.Visible = true;
    return true;
}
于 2013-07-23T08:38:01.943 回答
0

该异常有两个可能的原因:

  • 调用调用时未创建表单
  • 您可能在错误的线程上创建控件

你应该总是InvokeRequired在调用之前检查属性,当然在此之前检查 null

public bool StartFormB()
{
    if (frB == null)
    {
        throw new ArgumentNullException("frB");
    }

   if (frB.InvokeRequired)
   {

        frB.Invoke(new EventHandler(DisplayFrmB));
   }
   else
   {    
      if (frB.IsDisposed)
      {
        throw new ObjectDisposedException("Control is already disposed.");
      }
  }

  return true;
}
于 2013-07-23T05:43:02.017 回答
0

如果控件的 Visible 属性为 false,则不会创建控件句柄。当您调用 Invoke 时,您在委托中将控件的可见状态设置为 true,但尚未创建句柄,因此您不能调用 Invoke。所以 - 你必须调用 frB.CreateHandle(); 之后:frB = new frmB(); 强制创建控制句柄

    private SessionMgmt()
    {
        frB = new frmB();
        var h = frB.Handle;
    }
于 2013-07-23T07:17:14.227 回答
0

Windows 窗体是 Windows API 的包装器,该异常意味着尚未创建基础窗口。我认为它是在您第一次设置为时创建Visibletrue,并且还有其他一些情况可以这样做。

请参阅此链接以获取可能的解决方案:http: //blogs.msdn.com/b/mapo/archive/2011/04/27/forcing-handle-creation-in-a-net-windows-forms-control.aspx

于 2013-07-23T05:39:35.810 回答