0

2 つのフォームと 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();
    }

}

これが私のformBです。

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

0

Windows フォームは Windows API のラッパーであり、その例外は、基になるウィンドウがまだ作成されていないことを意味します。初めて設定Visibleしたときに作成されると思いますが、それを行う状況は他にもいくつかあります。true

考えられる解決策については、次のリンクを参照してください。

于 2013-07-23T05:39:35.810 に答える
0

コントロールの Visible プロパティが false の場合、コントロール ハンドルは作成されません。Invoke を呼び出すと、デリゲートでコントロールの表示状態を true に設定しますが、ハンドルはまだ作成されていないため、Invoke を呼び出すことはできません。したがって、frB.CreateHandle(); を呼び出す必要があります。後: frB = 新しい frmB(); コントロールハンドルの作成を強制する

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

その例外には 2 つの理由が考えられます。

  • インボークが呼び出されたときにフォームが作成されない
  • 間違ったスレッドでコントロールを作成している可能性があります

呼び出す前に常に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 に答える