- PR -

MDI親フォームのToolBarを切り替えるには?

投稿者投稿内容
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2005-10-21 18:31
引用:

上記の部分だけですが、MDIの仕様のような気がしてならないです。。。


やはり再現しました。
新しいフォームが表示されるたびにVisible=Trueになりました。
#最大化ではなくノーマルです。
表示済み子フォームの切り替え(タイトルバークリック)ではならないようです。

MDIClientクラスの挙動が関連しているかもしれません。
high4
会議室デビュー日: 2005/08/23
投稿数: 7
投稿日時: 2005-10-22 00:35
これはやはり、すなおに、
1. 親のMDIコンテナで 全ての toolbar のインスタンスを持つ。( デザイナで drop&down )
2. 最初は、Visible=false で MDIコンテナ_Load() をスタート。
3. 子の MDIクライアントで、 Activated のイベントの中から、親のMDIコンテナに処理を依頼する。
コード:
Child_Activated(..)
{
	MdiParentを親にキャストして.SetTheToolbar(this);
}


4. 親のMDIコンテナで
コード:
void SetTheToolbar(Form frm)
{
	SuspendLayout();
	frm に対応する toolStrip.Visible = true; ( if frm is child1 then などとして)
	その他の全ての toolStrip.Visible = false;
	ResumeLayout();
}


という入り方が無難だと思うのですが。

上記の方法では、1つの子クラスの複数のインスタンスが、共通した その子クラス目的用の1つの toolbar を共用することになります。
子クラスのインスタンスごとに独自の toolbar の状態を占有したいなら、子クラスの new の時点で、親コンテナが その子クラス目的用の toolbar を new して配列などで管理する方法も取れます。

この方法では、子クラスの Closing がキャンセルされ Hide() にギアチェンジするようなことをしても、別に影響は無いでしょう。
ただ1つ、全ての子クラスがClose や Hide したときに toolbar を全て unvisible にすることをMDIコンテナが検査する必要が有ります。
子クラスの Deactivate の都度、 visible = false にすると、SuspendLayout();が2度発生するので画面がちらつくでしょう。
それから、 Add,Removeは使わないほうが、toolbar の状態の保存/復元が手間ですから、 Visible/UnVisible がスマートです。

という方針でいけば、何とかなると思います。( だめだったらゴメンナサイ )
ともかく、 WM_ACTIVATE( 得る又は失う ) は曲者ですから、その出現する順番を意図するようなことにあまり関わると夜も眠れなくなりますよ。
あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2005-10-24 09:59
high4さん、

それは、冒頭の
引用:

(3) 親フォームにToolBarを子フォームの数分持たせておき、Show()、Hide()を
切り替える。


にあたると思うのです。

原因はAdd,Removeではないと思うのですが、
現象はほぼ同じです。

違いは、「A」を最小化して閉じた後、「B」を開くと
初期状態が最大化にならないのと、「B」自体もクリックに
反応しなくなります(クローズボタンは押せます)。

以下はそのコード断片です。

コード:
private void toolBarA_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
{
	switch (toolBarA.Buttons.IndexOf(e.Button))
	{
		case 0:
			this.ShowFormA();
			break;
		case 1:
			this.ShowFormB();
			break;
		case 2:
			this.ShowFormC();
			break;
		default:
			break;
	}
}

private void toolBarB_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
{
	switch (toolBarB.Buttons.IndexOf(e.Button))
	{
		case 0:
			this.ShowFormA();
			break;
		case 1:
			this.ShowFormB();
			break;
		case 2:
			this.ShowFormC();
			break;
		default:
			break;
	}
}

private void toolBarC_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
{
	switch (toolBarC.Buttons.IndexOf(e.Button))
	{
		case 0:
			this.ShowFormA();
			break;
		case 1:
			this.ShowFormB();
			break;
		case 2:
			this.ShowFormC();
			break;
		default:
			break;
	}
}

private void ShowFormA()
{
	if (this.childFormA == null)
	{
		this.childFormA = new FormA();
		this.childFormA.MdiParent = this;
	}
	this.childFormA.Show();
	this.childFormA.Activate();
}

private void ShowFormB()
{
	if (this.childFormB == null)
	{
		this.childFormB = new FormB();
		this.childFormB.MdiParent = this;
	}
	this.childFormB.Show();
	this.childFormB.Activate();
}

private void ShowFormC()
{
	if (this.childFormC == null)
	{
		this.childFormC = new FormC();
		this.childFormC.MdiParent = this;
	}
	this.childFormC.Show();
	this.childFormC.Activate();
}

private void FormABC_MdiChildActivate(object sender, System.EventArgs e)
{
	if (this.ActiveMdiChild != null)
	{
		if (this.ActiveMdiChild == this.childFormA)
		{
			if (this.toolBarB.Visible == true)
			{
				this.toolBarB.Hide();
			}
			if (this.toolBarC.Visible == true)
			{
				this.toolBarC.Hide();
			}
			if (this.toolBarA.Visible == false)
			{
				this.toolBarA.Show();
			}
		}
		else if (this.ActiveMdiChild == this.childFormB)
		{
			if (this.toolBarA.Visible == true)
			{
				this.toolBarA.Hide();
			}
			if (this.toolBarC.Visible == true)
			{
				this.toolBarC.Hide();
			}
			if (this.toolBarB.Visible == false)
			{
				this.toolBarB.Show();
			}
		}
		else if (this.ActiveMdiChild == this.childFormC) 
		{
			if (this.toolBarA.Visible == true)
			{
				this.toolBarA.Hide();
			}
			if (this.toolBarB.Visible == true)
			{
				this.toolBarB.Hide();
			}
			if (this.toolBarC.Visible == false)
			{
				this.toolBarC.Show();
			}
		}
	}
}


あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2005-10-24 14:50
結局、ツールバーはあまり関係なく、
MDI子フォームの最小化後の動作に問題があると認識し、

MSDN Product Feedback Center Home
http://lab.msdn.microsoft.com/productfeedback/Default.aspx

に、

「MDI子フォームを最小化して閉じると後の動作が不正になる」
(Bug ID:FDBK39149)

として、報告しました。

Voteお願いします!
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-24 15:06
こちらの URL で貼らないと Vote してくれる人が減少しますよ。(^^)
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=61c2dd24-1ffb-4047-83ad-b5fef5d83dab

# MDI 子フォーム周りの不具合は他にもいくつかありましたね...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2005-10-24 15:32
じゃんぬねっとさん、さんきゅーです。

同じ原因っぽいのもありましたが、再現しないと却下されてたり
しましたね。。。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2005-10-24 15:42
自前のMDIアプリでe.Cancel=True,Me.Hideを追加して試してみました。(VB.NET)
普通にShow、最小化+X、別Form.Showで現れますね。現象も再現します。
Spyで見る限りちゃんとMDIClientにぶら下がってるようです。
・タイトルバーがアクティブにならない
・WindowList属性のメニューで選択するとちゃんと前面に来る
・クライアントエリアではみ出してもスクロールバーが出ない
・フォーム無し+普通にShow、最小化+Xの状態で、WindowListメニューにセパレータが残っている
・MDIChildrenプロパティは大丈夫そう
・MDIChildActivateイベントは起こっていないか、起こってもNothingになっていると思われ

なんか、MDIClientの配下にいるけれど、管理対象のStyleから外れてしまっている
という感じでしょうか。
MDI親フォームがどうのこうのではないでしょうね。
以上、私観。
high4
会議室デビュー日: 2005/08/23
投稿数: 7
投稿日時: 2005-10-24 16:20
あぶぽんさんの指摘されているポイントをこちらが理解できていないのかもしれません。

そこで、あぶぽんさんの意図に合わせた(と思う)コードを書いてみました。
まず、VS2005 RC で作成しました。
方針は、前回お話したそのままです。結果は予定通りの動作でした。

次に、それをVS2003 で書き直してみました。VS2005::tooStrip と VS2003::toolbar の扱いがちょっと異なるのでその部分だけの変更になりました。結果はこれも問題ありませでした。
つまり、FormA,B,C にフォーカスを変えたときの toolbar の状態や、最小化したり等、色々しましたが、特に奇妙なことは生じませんでした。

あとはこちらが理解していないという可能性が残ります。
そこで、後にVS2003 のソースコードを添付しておきます。
最初に、FormABC の部分、次に FormA の部分、FormB,C は FormA を参考にしてください。

細かなことですが、toolBarA_ButtonClick() の中で、
this.ShowFormA();に続いて frmA.Activate();とあぶぽんさんのコードに従って書いていますが、frmA.Focus(); とするのが素直だと思います。

前回お話した方針は Windows の「行儀正しく、安全で、使い古された方法」ですので、この方針を起点に、仕様に従って付加していけば良いのではと思います。

では以下、ただ単に冗長なソースコードだけが続きます。
( 関係者以外はここで立ち去ることをお勧めします )
以上。

コード:
FormABC.cs
----------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace ChangeToolbar2003
{
	/// <summary>
	/// Form1 の概要の説明です。
	/// </summary>
	public class FormABC : System.Windows.Forms.Form
	{
		private System.Windows.Forms.ToolBar toolBarA;
		private System.Windows.Forms.ToolBarButton toolBarButtonA1;
		private System.Windows.Forms.ToolBarButton toolBarButtonA2;
		private System.Windows.Forms.ToolBarButton toolBarButtonA3;
		private System.Windows.Forms.ToolBar toolBarB;
		private System.Windows.Forms.ToolBar toolBarC;
		private System.Windows.Forms.ToolBarButton toolBarButtonB1;
		private System.Windows.Forms.ToolBarButton toolBarButtonB2;
		private System.Windows.Forms.ToolBarButton toolBarButtonB3;
		private System.Windows.Forms.ToolBarButton toolBarButtonC1;
		private System.Windows.Forms.ToolBarButton toolBarButtonC2;
		private System.Windows.Forms.ToolBarButton toolBarButtonC3;
		/// <summary>
		/// 必要なデザイナ変数です。
		/// </summary>
		private System.ComponentModel.Container components = null;

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

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

		/// <summary>
		/// 使用されているリソースに後処理を実行します。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows フォーム デザイナで生成されたコード 
		/// <summary>
		/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
		/// コード エディタで変更しないでください。
		/// </summary>
		private void InitializeComponent()
		{
			this.toolBarA = new System.Windows.Forms.ToolBar();
			this.toolBarButtonA1 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonA2 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonA3 = new System.Windows.Forms.ToolBarButton();
			this.toolBarB = new System.Windows.Forms.ToolBar();
			this.toolBarC = new System.Windows.Forms.ToolBar();
			this.toolBarButtonB1 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonB2 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonB3 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonC1 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonC2 = new System.Windows.Forms.ToolBarButton();
			this.toolBarButtonC3 = new System.Windows.Forms.ToolBarButton();
			this.SuspendLayout();
			// 
			// toolBarA
			// 
			this.toolBarA.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
																						this.toolBarButtonA1,
																						this.toolBarButtonA2,
																						this.toolBarButtonA3});
			this.toolBarA.DropDownArrows = true;
			this.toolBarA.Location = new System.Drawing.Point(0, 0);
			this.toolBarA.Name = "toolBarA";
			this.toolBarA.ShowToolTips = true;
			this.toolBarA.Size = new System.Drawing.Size(608, 41);
			this.toolBarA.TabIndex = 1;
			this.toolBarA.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBarA_ButtonClick);
			// 
			// toolBarButtonA1
			// 
			this.toolBarButtonA1.Text = "A1";
			// 
			// toolBarButtonA2
			// 
			this.toolBarButtonA2.Text = "A2";
			// 
			// toolBarButtonA3
			// 
			this.toolBarButtonA3.Text = "A3";
			// 
			// toolBarB
			// 
			this.toolBarB.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
																						this.toolBarButtonB1,
																						this.toolBarButtonB2,
																						this.toolBarButtonB3});
			this.toolBarB.DropDownArrows = true;
			this.toolBarB.Location = new System.Drawing.Point(0, 41);
			this.toolBarB.Name = "toolBarB";
			this.toolBarB.ShowToolTips = true;
			this.toolBarB.Size = new System.Drawing.Size(608, 41);
			this.toolBarB.TabIndex = 3;
			this.toolBarB.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBarB_ButtonClick);
			// 
			// toolBarC
			// 
			this.toolBarC.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
																						this.toolBarButtonC1,
																						this.toolBarButtonC2,
																						this.toolBarButtonC3});
			this.toolBarC.DropDownArrows = true;
			this.toolBarC.Location = new System.Drawing.Point(0, 82);
			this.toolBarC.Name = "toolBarC";
			this.toolBarC.ShowToolTips = true;
			this.toolBarC.Size = new System.Drawing.Size(608, 41);
			this.toolBarC.TabIndex = 4;
			this.toolBarC.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBarC_ButtonClick);
			// 
			// toolBarButtonB1
			// 
			this.toolBarButtonB1.Text = "B1";
			// 
			// toolBarButtonB2
			// 
			this.toolBarButtonB2.Text = "B2";
			// 
			// toolBarButtonB3
			// 
			this.toolBarButtonB3.Text = "B3";
			// 
			// toolBarButtonC1
			// 
			this.toolBarButtonC1.Text = "C1";
			// 
			// toolBarButtonC2
			// 
			this.toolBarButtonC2.Text = "C2";
			// 
			// toolBarButtonC3
			// 
			this.toolBarButtonC3.Text = "C3";
			// 
			// FormABC
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
			this.ClientSize = new System.Drawing.Size(608, 374);
			this.Controls.Add(this.toolBarC);
			this.Controls.Add(this.toolBarB);
			this.Controls.Add(this.toolBarA);
			this.IsMdiContainer = true;
			this.Name = "FormABC";
			this.Text = "FormABC";
			this.Load += new System.EventHandler(this.FormABC_Load);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// アプリケーションのメイン エントリ ポイントです。
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new FormABC());
		}

		private void toolBarA_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			switch (toolBarA.Buttons.IndexOf(e.Button))
			{
				case 0:
					this.ShowFormA();
					frmA.Activate();
					break;
				case 1:
					this.ShowFormB();
					frmB.Activate();
					break;
				case 2:
					this.ShowFormC();
					frmC.Activate();
					break;
			}
		
		}

		private void toolBarB_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			switch (toolBarB.Buttons.IndexOf(e.Button))
			{
				case 0:
					this.ShowFormA();
					frmA.Activate();
					break;
				case 1:
					this.ShowFormB();
					frmB.Activate();
					break;
				case 2:
					this.ShowFormC();
					frmC.Activate();
					break;
			}
		}

		private void toolBarC_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			switch (toolBarC.Buttons.IndexOf(e.Button))
			{
				case 0:
					this.ShowFormA();
					frmA.Activate();
					break;
				case 1:
					this.ShowFormB();
					frmB.Activate();
					break;
				case 2:
					this.ShowFormC();
					frmC.Activate();
					break;
			}
		}

		FormA frmA = null;
		FormB frmB = null;
		FormC frmC = null;

		private void FormABC_Load(object sender, System.EventArgs e)
		{
			toolBarA.Visible = false;
			toolBarB.Visible = false;
			toolBarC.Visible = false;

			ShowFormA();
			ShowFormB();
			ShowFormC();

		}

		private void ShowFormA()
		{
			if (frmA == null)
			{
				frmA = new FormA();
				frmA.MdiParent = this;
			}
			frmA.Show();
		}

		private void ShowFormB()
		{
			if (frmB == null)
			{
				frmB = new FormB();
				frmB.MdiParent = this;
			}
			frmB.Show();
		}

		private void ShowFormC()
		{
			if (frmC == null)
			{
				frmC = new FormC();
				frmC.MdiParent = this;
			}
			frmC.Show();
		}

		public void SetTheToolbar(Form frm)
		{
			SuspendLayout();
			if (frm is FormA)
			{
				this.toolBarA.Visible = true;
				this.toolBarB.Visible = false;
				this.toolBarC.Visible = false;
			}
			else if (frm is FormB)
			{
				this.toolBarA.Visible = false;
				this.toolBarB.Visible = true;
				this.toolBarC.Visible = false;
			}
			else if (frm is FormC)
			{
				this.toolBarA.Visible = false;
				this.toolBarB.Visible = false;
				this.toolBarC.Visible = true;
			}
			ResumeLayout();
		}

	}
}

FormA.cs
--------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace ChangeToolbar2003
{
	/// <summary>
	/// FormA の概要の説明です。
	/// </summary>
	public class FormA : System.Windows.Forms.Form
	{
		/// <summary>
		/// 必要なデザイナ変数です。
		/// </summary>
		private System.ComponentModel.Container components = null;

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

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

		/// <summary>
		/// 使用されているリソースに後処理を実行します。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows フォーム デザイナで生成されたコード 
		/// <summary>
		/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
		/// コード エディタで変更しないでください。
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// FormA
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
			this.ClientSize = new System.Drawing.Size(292, 266);
			this.Name = "FormA";
			this.Text = "FormA";
			this.Closing += new System.ComponentModel.CancelEventHandler(this.FormA_Closing);
			this.Activated += new System.EventHandler(this.FormA_Activated);

		}
		#endregion

		private void FormA_Activated(object sender, System.EventArgs e)
		{
			((FormABC)MdiParent).SetTheToolbar(this);
		}

		private void FormA_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = true;
			Hide();
		}
	}
}





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