2009-06-01 15 views
0

サブフォーム(ShowDialog)を開くことができるフォームがあります。私は、メインフォームが完了したときにサブフォームが適切に配置されていることを確認したい。 サブフォームをメインフォームのcomponentsメンバーに追加しようとしましたが、現時点ではArgumentNullExceptionがあります。
自分でcomponentsをインスタンス化することはできますが、少し危険ですか?ある日、デザイナビューにコンポーネントを追加すると、designer.csファイルにnew Container()行が生成され、ヒープの周りを2つのコンポーネントインスタンスが実行されていることはわかりません。
サブフォームが廃棄されていることを確認する簡単な方法はありますか?フォームが配置されたときにサブフォームを配置するWinForm

EDITは - あなたはShowDialogのでフォームを使用している場合は、1あなたが結果を受け取った後、あなたがそこにフォームを配置できることを前提と可能性が答え

答えて

0

私の現在の回避策:私は、フォームにコンポーネントのプロパティを追加した、とサブフォームを複数回開くことができ

private IContainer Components{ get { return components ?? (components = new Container());}} 
3

に私の解決策を動かし? ShowDialog()経由で呼び出さMSDN、モーダルフォームを1として

using(MyDialog dlg = new MyDialog()) 
{ 
    result = dlg.ShowDialog(); 
} 
+0

コレクションにアクセスするためにそれを使用しています
異なるデータ。私はそれを開くたびに新しいインスタンスを作成したくありません。 –

+0

しかし、なぜあなたはそれを処分することを心配していますか?ショーのダイアログ呼び出しの後に削除されないリソースは、どのリソースで使用していますか? – Spence

+0

ShowDialogの後、フォームは自動的に処理されません。この方法で私はDialogResultにアクセスすることができます(これは自動的にそれを処理しない理由です)。ShowDialogを何度も何度も繰り返し使用しています。 メインフォームの廃棄時にサブフォームが廃棄されていることを確認したい。 –

0

は自動的に配置されていないと責任はそれらを配置する開発者である:フォームをクリックし、モーダルダイアログボックスとして表示され

閉じるボタン(フォームの右上隅にXが付いたボタン)をクリックすると、フォームが非表示になり、DialogResultプロパティがDialogResult.Cancelに設定されます。モードレスフォームとは異なり、ユーザーがダイアログボックスのフォームを閉じるボタンをクリックするか、DialogResultプロパティの値を設定すると、.NET FrameworkではCloseメソッドは呼び出されません。代わりにフォームが非表示になり、ダイアログボックスの新しいインスタンスを作成せずに再び表示できます。ダイアログボックスとして表示されるフォームは閉じられていないため、アプリケーションでフォームが不要になったときに、フォームのDisposeメソッドを呼び出す必要があります。

ここでの関連ポイントは、「フォームが必要なくなったとき」です。あなたのケースでは、後続のアクションのためにフォームが必要なように見えるので、ShowDialog()コールをusingコンストラクトにラップすることは目的を果たしません。

私の提案は、可能な限り早期に自分のメインフォームのDisposeメソッドでダイアログを処分、またはするために、次のようになります。

protected override void Dispose(bool disposing) 
{ 
    if (disposing && (components != null)) 
    { 
    components.Dispose(); 
    } 
    // dlg is a variable of type Form2(the dialog) 
    if (dlg != null) 
    { 
    dlg.Dispose(); 
    dlg = null; 
    } 
    base.Dispose(disposing); 
} 
+0

私はここでデザイナーとどうやってやっていくのがポイントかと思います。通常、disposeは.Designer.csに部分的に宣言されていません。 –

+0

はい、私はそれを認識しています。クラスレベルの変数はDesigner.csに表示されます。 – Cerebrus

1

それはalread定義されていますので、あなたは通常、フォームの破棄して下さいメソッドをオーバーライドすることはできませんForm.Designer.csファイルに保存します。フォームに独自のディスポジションロジックを追加する方法は少しあります。サブフォームのリストを保持してのMainFormのコンストラクタに次の行を追加します

public class Disposer : Component 
    { 
     private readonly Action<bool> disposeAction;    

     public Disposer(Action<bool> disposeAction) 
     { 
      this.disposeAction = disposeAction; 
     } 

     protected override void Dispose(bool disposing) 
     { 
      base.Dispose(disposing); 
      this.disposeAction(disposing); 
     } 

     public static Disposer Register(ref IContainer container, Action<bool> disposeAction) 
     { 
      Disposer disposer = new Disposer(disposeAction); 
      if (container == null) 
       container = new System.ComponentModel.Container(); 

      container.Add(disposer); 
      return disposer; 
     } 
    } 

Disposer.Register(ref this.components, this.MyDisposeAction); 

あなたのMainFormが配置されている場合は、すべてのサブフォームも意志次のクラスを使用して

処分する、例えば:

private void MyDisposeAction(bool disposing) 
{ 
    if (disposing) 
    { 
    foreach (var subForm in this.subForms) 
    { 
     subForm.Dispose(disposing); 
    } 
    } 
} 
+0

アイデアありがとう、しかし、なぜ私はすべての私のサブフォームを保持するラッパークラスを作成する必要が表示されないし、次の後にそれらを廃棄した場合、私はコンポーネントで登録して方法は、必要に応じて) - 私はちょうどコンポーネントにすぐに私のサブフォームを登録することができます。それがそこにあるのです。 disposeメソッドの書き換えについて - 私はデザイナーコードから自分のファイルにコピーすると、それが再生成されないので、SOの別の場所を読んだことがあります。 –

関連する問題