C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

DataGridViewのカスタム列セル外表示

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■89447 / inTopicNo.1)  DataGridViewのカスタム列セル外表示
  
□投稿者/ Mimio (1回)-(2018/11/29(Thu) 13:17:39)

分類:[.NET 全般] 

C# Windows Form アプリケーション(Vidual Studio 2017)
DataGridViewのカスタム列型作成に関する質問です。
(NETに関しては、自己流学習のため、ほぼ初心者ですので、よろしくお願いします。)

TimeSpanに対応する24時超(26:30など)の時刻を表示できるユーザーコントロールを作成しました。TextBox(時)+TextBox(分)+Button+(通常非表示パネル+Button群)です。Buttonは通常非表示のパネルと表示し、入退室で打刻した他の時刻を表示し、選択でTimeSpanに入れるというものです。
ユーザーコントロールとカスタムColumnはできたつもりでいましたが、実際に動かすとDataGridViewのCell内にパネルが表示されてしまいいます。

質問は、この通常非表示のパネルをセルの外に表示したいというものです。
MonthCalendarやComboBoxをカスタム列型としたときに、右ボタンをクリックするとセル外にカレンダやList部分が表示されるので、何らかの設定でできるのではないかと思っています。

よろしくお願いします。

引用返信 編集キー/
■89448 / inTopicNo.2)  Re[1]: DataGridViewのカスタム列セル外表示
□投稿者/ 魔界の仮面弁士 (1958回)-(2018/11/29(Thu) 13:41:50)
No89447 (Mimio さん) に返信
> 実際に動かすとDataGridViewのCell内にパネルが表示されてしまいいます。
DataGridViewCell 継承クラスのサイズは、常にセルサイズに収まるようにします。
https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/8cd309b3-b2fc-480d-80b8-9f7cf56ecf22/


> MonthCalendarやComboBoxをカスタム列型としたときに、
> 右ボタンをクリックするとセル外にカレンダやList部分が表示されるので、
ComboBox でいえば、DropDownStyle = Simple スタイルでフォームに貼った場合、
テキスト部とリスト部を合わせた領域が、そのコントロールのサイズとして扱われますよね。

一方、DropDownStyle = DropDown / DropDownList の場合、
デザイン時、コントロールのサイズにリスト部は含まれていませんよね。


実行時で比較してみると、Simple スタイルの場合は
リスト部が親コントロール(Form など)内から出られませんが、
DropDown や DropDownList スタイルの場合には
リスト部が Form からはみ出していても表示できますよね。

これは、ドロップダウンやポップアップ表示するタイプのコントロールの場合、
追加で表示される領域は、そのコントロールの一部ではなく、
別のウィンドウが表示されているためである、と考えられます。


> 何らかの設定でできるのではないかと思っています。
パネル部はセル内に配置するのではなく、新規に Form を用意し、
そこに移動してみてください。
このフォームの TopLevel プロパティは false にしておきます(既定で false です)。

そして、TimeSpan セルがパネル入力モードになった段階で、
この子フォームを表示するようなコードを記述し、フォーカスをそこに移します。

あとは、コントロールからフォーカスが Leave したときに
そのフォームが消えるようにすれば、
ドロップダウンスタイルと同じ見た目になるかと。
引用返信 編集キー/
■89458 / inTopicNo.3)  Re[2]: DataGridViewのカスタム列セル外表示
□投稿者/ mimio (1回)-(2018/11/30(Fri) 03:48:56)
No89448 (魔界の仮面弁士 さん) に返信
余計なことを書くと怒られるかも知れませんが、
直接ご回答頂いたことはありませんでしたが、
以前らご高名な魔界の仮面弁士様にはお世話になっております。
今後も一層のご活躍をお祈り致します。

> ■No89447 (Mimio さん) に返信
>>実際に動かすとDataGridViewのCell内にパネルが表示されてしまいいます。
> DataGridViewCell 継承クラスのサイズは、常にセルサイズに収まるようにします。
> https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/8cd309b3-b2fc-480d-80b8-9f7cf56ecf22/

じっくりを読んでみることにします。

>>MonthCalendarやComboBoxをカスタム列型としたときに、
>>右ボタンをクリックするとセル外にカレンダやList部分が表示されるので、
> ComboBox でいえば、DropDownStyle = Simple スタイルでフォームに貼った場合、
> テキスト部とリスト部を合わせた領域が、そのコントロールのサイズとして扱われますよね。
>
> 一方、DropDownStyle = DropDown / DropDownList の場合、
> デザイン時、コントロールのサイズにリスト部は含まれていませんよね。
>
>
> 実行時で比較してみると、Simple スタイルの場合は
> リスト部が親コントロール(Form など)内から出られませんが、
> DropDown や DropDownList スタイルの場合には
> リスト部が Form からはみ出していても表示できますよね。

Simple スタイルのテストは行いませんでしたが、なるほどです。

> これは、ドロップダウンやポップアップ表示するタイプのコントロールの場合、
> 追加で表示される領域は、そのコントロールの一部ではなく、
> 別のウィンドウが表示されているためである、と考えられます。
>

別のウィンドウが表示されている?
DataGridViewCellの設定でできることではないとお考えなのですね。

>
>>何らかの設定でできるのではないかと思っています。
> パネル部はセル内に配置するのではなく、新規に Form を用意し、
> そこに移動してみてください。
> このフォームの TopLevel プロパティは false にしておきます(既定で false です)。
>
> そして、TimeSpan セルがパネル入力モードになった段階で、
> この子フォームを表示するようなコードを記述し、フォーカスをそこに移します。
>
> あとは、コントロールからフォーカスが Leave したときに
> そのフォームが消えるようにすれば、
> ドロップダウンスタイルと同じ見た目になるかと。

ユーザーコントロールに子フォームをくっつけることができるとは思いませんでした。
実際に行ってみます。
ありがとうございました。
引用返信 編集キー/
■89459 / inTopicNo.4)  Re[3]: DataGridViewのカスタム列セル外表示
□投稿者/ mimio (2回)-(2018/11/30(Fri) 05:06:38)
今まで、ユーザーコントロールにベタベタパネル等を貼り付けていましたが、
今回のことで、間違ったやり方であった事が分かりました。
ありがとうございました。




解決済み
引用返信 編集キー/
■89469 / inTopicNo.5)  Re[4]: DataGridViewのカスタム列セル外表示
□投稿者/ mimio (3回)-(2018/11/30(Fri) 13:37:38)
アローボタンクリックイベントに次のように書きました。

TimeSpanSelectForm sForm = new TimeSpanSelectForm();
sForm.TopLevel = false;
sForm.FormBorderStyle = FormBorderStyle.None;
this.Controls.Add(sForm);
sForm.Location = new Point(20, TimefLPanel.Height); //入力部のパネルの高さ分下に下げる
sForm.Show();
sForm.BringToFront();


DataGridViewでは
this.Controls.Add(sForm);
だと、thisがIDataGridViewEditingControlとなり、
DataGridViewのCell枠内に表示されるので、
this.Parent.Parent.Controls.Add(sForm);
としました。
Location位置を直せば、
this.Controls.Add(sForm);
のthisは、IDataGridViewEditingControlなので、
DataGridViewのCell内表示となりました。

解決済み
引用返信 編集キー/
■89470 / inTopicNo.6)  Re[5]: DataGridViewのカスタム列セル外表示
□投稿者/ 魔界の仮面弁士 (1960回)-(2018/11/30(Fri) 14:27:56)
2018/11/30(Fri) 15:04:31 編集(投稿者)

No89469 (mimio さん) に返信
> sForm.TopLevel = false;

ごめんなさい!
先の No89448 の回答で、TopLevel の true/false を逆に書いていました…。

自分のイメージしていた処理は
 sForm.TopLevel = true; // 初期値で既に true
 sForm.Deactivate += delegate { sForm.Close(); };
 sForm.Show(Form.ActiveForm);
という物です。(子コントロールとするわけではない)

Deactivate イベントは、sForm 以外の場所をクリックした場合に
キャンセル扱いとしてパネルフォームを閉じるために挿入しています。

ただしこの方法だと、ActiveForm がパネルフォーム側に移ってしまうのが難点です。

また、上記は親フォームがモードレスであることを想定しています。

ShowDialog で表示されたモーダル ウィンドウ上にある DataGridView からも
一応呼び出せますが、その場合、そのモーダルウィンドウの
呼び出し元(オーナーウィンドウ)をクリックした場合は、
Deactivate イベントが発生しません。
(モーダルフォーム自身をクリックした場合は、Deactivate が発生する)


> DataGridViewのCell枠内に表示されるので、
> this.Parent.Parent.Controls.Add(sForm);
> としました。

子コントロールとして配置する場合は、こういう風にも書けます。


DataGridView 上に配置したい場合
 // IDataGridViewEditingControl.EditingControlDataGridView プロパティ
 this.EditingControlDataGridView.Controls.Add(sForm);

親 Form 上に配置したい場合
 // Control.FindForm メソッド
 this.FindForm().Controls.Add(sForm);


ただしこの方法をとる場合、Controls.Add メソッドに渡すのは
TopLevel = false な Form ではなく、Panel 等の方が良さそうです。
引用返信 編集キー/
■89496 / inTopicNo.7)  Re[6]: DataGridViewのカスタム列セル外表示
□投稿者/ mimio (4回)-(2018/11/30(Fri) 18:04:05)
No89470 (魔界の仮面弁士 さん) に返信
> 2018/11/30(Fri) 15:04:31 編集(投稿者)
>
> ■No89469 (mimio さん) に返信
>>sForm.TopLevel = false;
>
> ごめんなさい!
> 先の No89448 の回答で、TopLevel の true/false を逆に書いていました…。
>
> 自分のイメージしていた処理は
>  sForm.TopLevel = true; // 初期値で既に true
>  sForm.Deactivate += delegate { sForm.Close(); };
>  sForm.Show(Form.ActiveForm);
> という物です。(子コントロールとするわけではない)
>
> Deactivate イベントは、sForm 以外の場所をクリックした場合に
> キャンセル扱いとしてパネルフォームを閉じるために挿入しています。
>
> ただしこの方法だと、ActiveForm がパネルフォーム側に移ってしまうのが難点です。
>
> また、上記は親フォームがモードレスであることを想定しています。
>
> ShowDialog で表示されたモーダル ウィンドウ上にある DataGridView からも
> 一応呼び出せますが、その場合、そのモーダルウィンドウの
> 呼び出し元(オーナーウィンドウ)をクリックした場合は、
> Deactivate イベントが発生しません。
> (モーダルフォーム自身をクリックした場合は、Deactivate が発生する)
>
>
>>DataGridViewのCell枠内に表示されるので、
>>this.Parent.Parent.Controls.Add(sForm);
>>としました。
>
> 子コントロールとして配置する場合は、こういう風にも書けます。
>
>
> DataGridView 上に配置したい場合
>  // IDataGridViewEditingControl.EditingControlDataGridView プロパティ
>  this.EditingControlDataGridView.Controls.Add(sForm);
>
> 親 Form 上に配置したい場合
>  // Control.FindForm メソッド
>  this.FindForm().Controls.Add(sForm);
>
>
> ただしこの方法をとる場合、Controls.Add メソッドに渡すのは
> TopLevel = false な Form ではなく、Panel 等の方が良さそうです。

いろいろな方法があるんですね。
いくつか試してみて、最も良さそうなものを探してみます。
しばらく、プログラミングから離れますので、
結果はかなり後になります。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ