- PR -

MDI環境において配置したコントロールの正しい位置を取得したいのですが・・・

1
投稿者投稿内容
MokiMoki
会議室デビュー日: 2004/11/22
投稿数: 19
投稿日時: 2005-05-25 11:39
件名の通り「コントロールの正しい位置」が取得できず苦戦しております。

●実現したいこと
・MDI内に「あるフォーム」の「あるコントロール(今回、ComboBox)」をクリックする
 とその直下にユーザコントロール(Windows.Forms内にDataGridを配置しています)を表
 示したい。
※通常のフォーム(MDIではないフォーム)では実現できました。
 Form frmfind = this.FindForm();
 popup.Location = new Point(find.Left + this.Left ,find.Top + this.Bottom + this.Height);
↑ユーザーコントロール

・MDIの場合ですとツールバーやメニューバーの関係により位置が異なっているようで
 す。
「ツールバーやメニューバーの位置 + MDI内にあるフォームの「あるコントロール」の
 位置」等で実現できそうですが苦戦しています。

●やったこと
・MDIの親フォーム配下の全コントロールをforeachで検索し、そのコントロールがツー
 ルバーやメニューバーであればその位置(Left,Top)を加算して表示しましたがダメで
 した。

どなたかヒントがあればご教授の程、宜しくお願い致します。

環境
VS.2003 C#
OS:WindowsXP SP2
MokiMoki
会議室デビュー日: 2004/11/22
投稿数: 19
投稿日時: 2005-05-25 11:51
すみません
誤字につき訂正致します。

誤:MDI環境において配置したコントロールの正しい位置を取得したいのですが・・・
正:MDIの子フォームに配置したコントロールの正しい位置を取得したいのですが・・・

環境はWindows.Formsです。
申し訳ございません。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-05-25 18:38
諸農です。

状況がよく判りませんが、子供のフォームにComboBoxとDataGrid、
ToolBar、Menuを貼り付けて、親側にはメニューのみを貼り付けて
次のコードで試してみましたが、ComboBoxの真下にDataGridは
位置付きますね。

コード:
    Point p = comboBox1.Location;
    p.Y += comboBox1.Height;
    dataGrid1.Location = p;




引用:

・MDIの場合ですとツールバーやメニューバーの関係により位置が異なっているようで
 す。



親フォームにメニューがあると、子側のメニューは親側にマージされますよね?
そういうことではないのかしらん?

再現できる具体例の提示をお願いします。

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
MokiMoki
会議室デビュー日: 2004/11/22
投稿数: 19
投稿日時: 2005-05-25 20:50
Jubei様、ご返信ありがとうございます。

>親フォームにメニューがあると、子側のメニューは親側にマージされますよね?
>そういうことではないのかしらん?
ご指摘の通り、子フォームのツールバーが親にマージされていました

>再現できる具体例の提示をお願いします。
説明不足でご迷惑をおかけしております。

↓仕様は↓
※ユーザーコントロール
(1)ComboBox
  MaxDropDownItems = 1
(2)Windows.Forms.Formを継承したフォームにDataGridを配置(仮にfrmPopupとします)
<主な機能>
・(1)が(2)を呼び出す機能になっています。
・(1)のComboBoxをDropDownすると真下にfrmPopupが表示される。
・(2)の表示位置は(1)で算出しています。(FindForm()を利用)
・何故、DataGridを使用したかというと、
 「ドロップダウンする項目に複数のフィールドを表示したい」
 という理由と
 「絞込み検索」を実現したいという理由です。
・勿論、部品化も目的としております。
  (表示する位置を自分自身で導き出せるようにしたい)

↓現状↓
※親フォーム
 メニューバー
 ツールバー(親フォームのツールバー)
 ツールバー(子フォームのツールバーがマージ)
※子フォーム
 Label,TextBox,ComboBox(ユーザコントロール)・・・・等々

事象
・子を持たない通常のフォームですと綺麗に真下に表示されます。
・配置したフォームが子の場合、ツールバーやメニューバー等の分だけ計算されていな
 いようで(すみません私の知識不足です)ユーザーコントロールの上に表示されてし
 まいます。

以上ですが説明が足りないようでしたらご指摘下さい。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-05-26 07:56
諸農です。

申し訳ないです。
どう読んでも、何がどうなっているのかよく判りません。

引用:

↓仕様は↓
※ユーザーコントロール
(1)ComboBox
  MaxDropDownItems = 1
(2)Windows.Forms.Formを継承したフォームにDataGridを配置(仮にfrmPopupとします)



ユーザーコントロールが(1)(2)を満たしているんでしょうか?
それとも(1)(2)は別物ですか?
(2)の継承フォームはIDEでデフォルトで作り出される通常のフォームでしょうか?
それともMokiMokiさんが作った何らかのフォームを継承したフォームでしょうか?

以下、私が行った手順です。

1.Formが3つでUserControlが1つのプロジェクトを用意。
2.Form1をMDI親にして、Form2をMDI子にします。
3.Form1にMainMenuを貼り付けてサブメニューを追加します。
4.Form2にMainMenuを貼り付けてサブメニューを追加します。
5.Form2にToolBarを貼り付けてボタンを追加します。
6.UserControlにComboBoxを一つ貼り付けます。
7.Form2のLoadイベントでUserControlを生成します。
8.ComboBoxのClickイベントハンドラで。。
8-1:ComboBoxのUserControl内における下端位置を求めます。
8-2:UserControlの座標変換メソッドで
    ComboBoxのスクリーン上での座標位置を求めます。
8-3:Form3を生成し、8-2で求めた座標位置をLocationに設定しShow()します。
 
コード:
    Point p = comboBox1.Location;
    p.Y += comboBox1.Height;
    p = this.PointToScreen(p);
    Form3 f = new Form3();
    f.Location = p;
    f.Show();



上記内容でComboBoxの下にフォームが表示されましたけど。。


引用:

・子を持たない通常のフォームですと綺麗に真下に表示されます。
・配置したフォームが子の場合、ツールバーやメニューバー等の分だけ計算されていな
 いようで(すみません私の知識不足です)ユーザーコントロールの上に表示されてし
 まいます。



書かれている内容がよく判りません。ごめんなさい。

再現の手順をお願いします。

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
MokiMoki
会議室デビュー日: 2004/11/22
投稿数: 19
投稿日時: 2005-05-26 08:08
Jubei様
朝早くからの返信ありがとうございます。

私が行った手順をまとめてみますので少しお時間を下さい。
それとJubei様が行った手順でも再度、試みてみます。

貴重なお時間ありがとうございました。
MokiMoki
会議室デビュー日: 2004/11/22
投稿数: 19
投稿日時: 2005-05-28 22:16
Jubei様
返信が遅れてしまいすみません。

確認と再現を行いました。
結論から言いますとJubei様が記述して頂いた「p = this.PointToScreen(p);」を
利用するとうまく真下に表示されました。


>どう読んでも、何がどうなっているのかよく判りません。
ごめんないさい。頑張って説明しているつもりでしたが・・・再度、試みます。

>ユーザーコントロールが(1)(2)を満たしているんでしょうか?
表示位置が思ったところに表示されないこと以外は私が考えてた通り変移しますので
内容は満たしていると私は理解しています。

>それとも(1)(2)は別物ですか?
別物です。(1)が(2)をインスタンス化して呼び出します。
(1)はComboBoxを継承したユーザーコントロールです。
(1)の中で(2)をインスタンス化しております。
その(1)のOnDropDownイベントをOrverrideしてDropDownイベント時に(2)の表示
する位置(※今回の問題点)を求めて表示する仕組みにしています。

>(2)の継承フォームはIDEでデフォルトで作り出される通常のフォームでしょうか?
>それともMokiMokiさんが作った何らかのフォームを継承したフォームでしょうか?
通常のWindowsフォーム(System.Windows.Forms.Form)を継承したクラスです。
そこにDataGridを配置しております。

>書かれている内容がよく判りません。ごめんなさい。
>再現の手順をお願いします。
MDIの内容
1.Form1:MDIの親
 ・親フォームのメニューバー+ツールバー+子フォームのツールバーがマージ
2.Form2:MDIの子
Label,TextBox,ComboBox(ユーザコントロール)・・・・等々

★ComboBox(ユーザコントロール)がドロップダウンされた際の変移(当初)
(コードを表示します。ご了承下さい)
 //ポップアップウィンドウ:表示位置の決定を行う
 Form frmcurrent = Form.ActiveForm; //親
 Form frmMdiChild = frmcurrent.ActiveMdiChild; //子
 Form frmfind = this.FindForm(); //コントロールがあるフォーム
 if (frmMdiChild == null)
 {  //MDI「無し」の場合
  frmpopup.Location
= new Point(frmfind.Left + this.Left
,frmfind.Top + this.Bottom + this.Height);
 }
 else
 {  //MDI「有り」の場合
  frmpopup.Location
= new Point(frmMdiChild.Left + this.Left
,frmMdiChild.Top + this.Bottom + this.Height);
 }
 ※MDI「無し」の場合はユーザコントロールの真下へ表示される。
 ※MDI「有り」の場合が予定の位置よりも上へ表示されてしまう。

★ComboBox(ユーザコントロール)がドロップダウンされた際の変移(Jubei様の例を参考)
//ポップアップウィンドウ:表示位置の決定を行う
Form frmfind = this.FindForm(); //コントロールがあるフォームを取得
Point p = this.Location; //Formを基準としたコントロールの位置
p.Y += this.Height; //真下に表示すべくコントロールの高さを考慮
p = frmfind.PointToScreen(p); //スクリーンを基準としたコントロールの位置を取得
frmpopup.Location = p;
 ※これでMDI「無し」「有り」関係なく全てOKになりました。


・スクリーンを基準とした「PointToScreen」の存在を知らずにLeftやBottomを使用して
位置を取得していました。
・スクリーンを基準とする「PointToScreen」に変更することで解決しております。


※私のよくわからない説明を読んで頂き、更に再現までして頂いて・・・・
 貴重なお時間を割いて頂き誠に感謝しております。
1

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