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

わんくま同盟

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

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


■87325 / )  Re[6]: パネルとスプリッターを使った時の処理方法
□投稿者/ 夜叉丸 (106回)-(2018/05/10(Thu) 18:39:06)
2018/05/10(Thu) 18:39:22 編集(投稿者)
No87323 (魔界の仮面弁士 さん) に返信
> ■No87308 (夜叉丸 さん) に返信
>>panel1の幅200、panel2の幅300をキープしたかったので、
> 
> フォームサイズが (150, 150) になったりすると、最小幅を維持できないので、
> Form の MinimumSize もセットしておいた方がよいかと思います。
> 
> 
> 現状だと、Form サイズが小さすぎた場合、
> panel1.Width = 200、panel2.Width = 0 になりえますし、
> それよりさらに狭くなると、panel1 に押しやられた splitter1 が
> マイナス座標に配置されることになりますよね。
> 
MinimumSize はセットしています。

> 具体的なサイズが分かると、こちらでも状況を追跡できるかも。
> 
> (1) Form の Width を幾つまで広げたのか
> (2) panel1 の Width をどこまで広げたのか
> (3) その後、Form の Width をどこまで狭めたのか

新規のフォームサイズを(526,339) で作成します。
フォントはデフォルトの [MSUIGothic, 13pt] を使ってます。
同時に MinimumSize = (526, 339) にします。

パネル(panel1)を貼り付け サイズを(200, 300)で、Dock = Right にします。
スプリッター(splitter1)を貼り付け サイズを(10, 300)で、Dock = Right にします。
パネル(panel1)を貼り付け サイズを(200, 300)で、Dock = Fill にします。
すると以下のようになります。
┌─────────────┐
│┌───┐┌─┐┌───┐│
││   ││S ││   ││
││   ││pt││   ││
││Panel1││le││Panel2││
││   ││ir││   ││
││   ││t1││   ││
│└───┘└─┘└───┘│
└─────────────┘
わかりやすく Panel1 の上に ListBox1 を、
Panel2 の上に ListBox2 を貼り付けて、どちらも DOCK=Fillにしました。
Panel1, Panel2 のリサイズイベントに以下のコードを追加します。

private void panel1_Resize(object sender, EventArgs e)
{
 if (panel1.Width < 200) panel1.Width = 200;
}

private void panel2_Resize(object sender, EventArgs e)
{
 if (panel2.Width < 300) panel1.Width = this.ClientSize.Width - 300 - splitter1.Width;
}

スプリッターの移動だけなら問題なく動きます。
ところが、フォームを広げ、panel2 の横幅を広げた状態にして
┌───────────────────┐
│┌───┐┌─┐┌─────────┐│
││   ││S ││         ││
││   ││pt││         ││ form (526,339) →(1500,339)
││Panel1││le││   Panel2   ││ panel1 (200,300) →(1000,300)
││   ││ir││         ││ panel2 (526,339) →(474,300)
││   ││t1││         ││
│└───┘└─┘└─────────┘│
└───────────────────┘
フォームの右端をドラッグしてフォームのサイズを素早く小さく
(フォームの右端をドラッグしたままマウスを左にすばやく移動)します。
ゆっくり動かすとならない、またはなりにくいです。
本来 panel1 と panel2 の幅の合計は 1078-26=1052 なのに
752+280=1032 になっている。その差 20 がグレー部分で表示されていると思います。
というより画面キャプチャ―して調べるとグレー部分が20増えていました。
┌───────────────┐
│┌───┐┌─┐┌───┐  │
││   ││S ││   │  │
││   ││pt││   │  │ form (1078,339)
││Panel1││le││Panel2│  │ panel1 (752,300)
││   ││ir││   │  │ panel2 (280,300)
││   ││t1││   │  │
│└───┘└─┘└───┘  │
└───────────────┘
              ↑
            グレー(Control色)の部分が表示される。

現状 ListBox が Panel2 の上に張り付けているので
フォームの内側が真っ白になることもありました。

>>壊れないようにするにはどうすればよいのでしょうか?
> もしも再配置が追いついていないようであれば、フォームのリサイズが終了した後で、
> ResumeLayout を呼び出してみるのはどうでしょう。
> https://dobon.net/vb/dotnet/control/suspendlayout.html
> 
 ResumeLayout を呼びましたが表示は変わりません。
 UpDate, Refresh も表示は変わりません。
 処理途中で強制終了されているような感じです。

> 
> SplitContainer なら、Resize イベント等のコーディングも不要で、
>  splitContainer1.SplitterWidth = 10
>  splitContainer1.Panel1MinSize = 300
>  splitContainer1.Panel2MinSize = 200
> をデザイン時に設定しておくだけで済むはずです。

はい、設定しました。

> それに Splitter をドラッグする際の視覚効果も、最小サイズ以下にならないよう調整されるので、
> ユーザビリティ的にも画面設計効率的にも、SplitContainer の方がお奨めです。
> 
> VS2005/VS2008 時代の MSDN を見てみると「SplitContainer コントロール (Windows フォーム)」の
> 解説において、下記のように記されていますしね。
> 
> 》メモ:
> 》 ツールボックスでは、以前のバージョンの Visual Studio で使用されていた Splitter コントロールが、
> 》 このコントロールに置き換えられました。SplitContainer コントロールの優先度は、Splitter コントロールよりも
> 》 かなり高くなります。Splitter クラスは、既存のアプリケーションとの互換性を確保するために、引き続き
> 》 .NET Framework に含まれていますが、新しいプロジェクトに対しては、SplitContainer コントロールを
> 》 使用することを強くお勧めします。 
> 
> ※ VS2017 では機械翻訳ヘルプになってしまったので分かり難い…。
> https://docs.microsoft.com/ja-jp/dotnet/framework/winforms/controls/splitcontainer-control-windows-forms

今後は SplitContainer を使用するようにします。



返信 編集キー/


管理者用

- Child Tree -