- PR -

一度閉じたFormを再度Showするとエラーになる

1
投稿者投稿内容
sora
会議室デビュー日: 2004/10/16
投稿数: 17
投稿日時: 2004-10-29 10:17
C#でWindowsアプリを作成しています。

作成中のアプリはMDIで作成しているのですが
子Formを×ボタンで閉じて親Formのメニューから
再度閉じたFormを開くと以下のようなエラーがでてしまいます。

"Form1" という名前の、破棄されたオブジェクトにアクセスできません。"

ソースは以下のようになっています
コード:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace FormShow
{
	/// <summary>
	/// FormMain の概要の説明です。
	/// </summary>
	public class FormMain : System.Windows.Forms.Form
	{
		/// <summary>
		/// 必要なデザイナ変数です。
		/// </summary>
		private System.ComponentModel.Container components = null;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.MenuItem menuItem3;
		private System.Windows.Forms.MenuItem menuItem4;
		Form1 frm1=null;
		Form2 frm2=null;
		Form3 frm3=null;

		public FormMain()
		{
			//
			// Windows フォーム デザイナ サポートに必要です。
			//
			InitializeComponent();

			//
			// TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
			//
		}

		/// <summary>
		/// 使用されているリソースに後処理を実行します。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		/// <summary>
		/// アプリケーションのメイン エントリ ポイントです。
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new FormMain());
		}

		#region Windows フォーム デザイナで生成されたコード 
		/// <summary>
		/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
		/// コード エディタで変更しないでください。
		/// </summary>
		private void InitializeComponent()
		{
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.menuItem1 = new System.Windows.Forms.MenuItem();
			this.menuItem2 = new System.Windows.Forms.MenuItem();
			this.menuItem3 = new System.Windows.Forms.MenuItem();
			this.menuItem4 = new System.Windows.Forms.MenuItem();
			// 
			// mainMenu1
			// 
			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem1});
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 0;
			this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem2,
																					  this.menuItem3,
																					  this.menuItem4});
			this.menuItem1.Text = "移動";
			// 
			// menuItem2
			// 
			this.menuItem2.Index = 0;
			this.menuItem2.Text = "Form1へ";
			// 
			// menuItem3
			// 
			this.menuItem3.Index = 1;
			this.menuItem3.Text = "From2へ";
			// 
			// menuItem4
			// 
			this.menuItem4.Index = 2;
			this.menuItem4.Text = "From3へ";
			// 
			// FormMain
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
			this.ClientSize = new System.Drawing.Size(718, 518);
			this.IsMdiContainer = true;
			this.Menu = this.mainMenu1;
			this.Name = "FormMain";
			this.Text = "FormMain";
			this.Load += new System.EventHandler(this.FormMain_Load);

		}
		#endregion

		private void FormMain_Load(object sender, System.EventArgs e)
		{
			frm1 = Form1.getInstance(); 
			frm1.MdiParent = this;
			//frm1.btn1Clicked += new Form1.Button1_Clicked(methodf2);
			frm1.button1.Click += new System.EventHandler(ToForm2_Click);
			frm1.button2.Click += new System.EventHandler(ToForm3_Click);
			frm1.Closed += new EventHandler(ChildFrom1_Closed);
			this.menuItem2.Click += new System.EventHandler(ToForm1_Click);
			this.menuItem3.Click += new System.EventHandler(ToForm2_Click);
			this.menuItem4.Click += new System.EventHandler(ToForm3_Click);
			frm1.Show(); 
			frm1.ActiveControl = null;
			frm1.SetFocus();
		}
		// オーバーライド
		//	重要
		protected override void UpdateDefaultButton() { } 
		// Form1クローズ処理
		private void ChildFrom1_Closed(object sender, EventArgs e) 
		{
			if (frm1!=null) {frm1=null;}
		}
		// Form2クローズ処理
		private void ChildFrom2_Closed(object sender, EventArgs e) 
		{
			if (frm2!=null) {frm2=null;}
		}
		// Form3クローズ処理
		private void ChildFrom3_Closed(object sender, EventArgs e) 
		{
			if (frm3!=null) {frm3=null;}
		}
		// Form1表示処理
		private void ToForm1_Click(object sender, System.EventArgs e)
		{
			if (frm1==null)
			{
				frm1 = Form1.getInstance(); 
				frm1.MdiParent = this;
				frm1.button1.Click += new System.EventHandler(ToForm2_Click);
				frm1.button2.Click += new System.EventHandler(ToForm3_Click);
				frm1.Closed += new EventHandler(ChildFrom1_Closed);
				this.menuItem2.Click += new System.EventHandler(ToForm1_Click);
				this.menuItem3.Click += new System.EventHandler(ToForm2_Click);
				this.menuItem4.Click += new System.EventHandler(ToForm3_Click);
			}


			frm1.Show();
			
			frm1.ActiveControl = null;
			if (frm2!=null) 
			{
				frm2.Hide();
				frm2.ActiveControl = null;
			}
			if (frm3!=null) 
			{
				frm3.Hide();
				frm3.ActiveControl = null;
			}
			frm1.SetFocus();
		}
		// Form2表示処理
		private void ToForm2_Click(object sender, System.EventArgs e)
		{
			if (frm2==null)
			{
				frm2 = Form2.getInstance(); 
				frm2.MdiParent = this;
				frm2.button1.Click += new System.EventHandler(ToForm1_Click);
				frm2.button2.Click += new System.EventHandler(ToForm3_Click);
				frm2.Closed += new EventHandler(ChildFrom2_Closed);
			}

			frm2.Show();
			frm2.ActiveControl = null;
			
			if (frm1!=null) 
			{
				frm1.Hide();
				frm1.ActiveControl = null;
			}
			if (frm3!=null) {
				frm3.Hide();
				frm3.ActiveControl = null;
			}
			frm2.SetFocus();
		}
	
		// Form3表示処理
		private void ToForm3_Click(object sender, System.EventArgs e)
		{
			if (frm3==null)
			{
				frm3 = Form3.getInstance(); 
				frm3.MdiParent = this;
				frm3.button1.Click += new System.EventHandler(ToForm1_Click);
				frm3.button2.Click += new System.EventHandler(ToForm2_Click);
				frm3.Closed += new EventHandler(ChildFrom3_Closed);
			}

			frm3.Show();
			frm3.ActiveControl = null;
			
			if (frm1!=null) 
			{
				frm1.Hide();
				frm1.ActiveControl = null;
			}
			if (frm2!=null) {
				frm2.Hide();
				frm2.ActiveControl = null;
			}
			frm3.SetFocus();
		}
	}
}




破棄されたオブジェクト(ここではfrm1など)を再度Showしたいのですが
どうしたら良いのでしょうか?

長文でもうしわけありませんがよろしくおねがいします
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2004-10-29 10:49
引用:

破棄されたオブジェクト(ここではfrm1など)を再度Showしたいのですが
どうしたら良いのでしょうか?



どうしようもありません。
廃棄されてしまったものを再度表示するすべは無いです。(Form や Control がそういう仕様のため)

閉じる以前のフォームの状態を維持する必要がなければ、再度 new Form1 で新しいインスタンスを作成し、それを表示します。

以前の状態を保持している必要があるなら、フォームの Closing イベントハンドラで

e.Cancel = true;
this.Visible = false;

などのようにクローズ動作をキャンセルして、代わりにフォームを不可視化します。

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
sora
会議室デビュー日: 2004/10/16
投稿数: 17
投稿日時: 2004-10-29 16:53
ひどりさん、返信ありがとうがざいます。

引用:

以前の状態を保持している必要があるなら、フォームの Closing イベントハンドラで

e.Cancel = true;
this.Visible = false;

などのようにクローズ動作をキャンセルして、代わりにフォームを不可視化します。


この処理で対応したいと思います。

本当にありがとうございました。

まだまだ勉強不足だな
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2004-10-29 17:42
引用:

引用:

などのようにクローズ動作をキャンセルして、代わりにフォームを不可視化します。


この処理で対応したいと思います。



おそらく気づいていると思いますが、↑に変更を行う際には、あわせてフォームのオープン処理もシナリオに合うように適切に修正してくださいね。
1

スキルアップ/キャリアアップ(JOB@IT)