パネル色々
Canvasよりもこっちの3種のパネルの方がよく使います。
Canvasでは子要素の各コントロール内で厳密な座標を指定して配置しましたが、ここで紹介する~Panelは自動的にいい感じに並べてくれます。
これらのPanelではCanvasと異なりAddChildを呼び出す順番によって子要素の配置が変わるため、ここは注意が必要です。
また、ほとんどのコントロールでVerticalAlignmentとHorizontalAlignmentのデフォルト値はCenterとなっているのですが、StackPanelとWrapPanelは一部異なりますのでご注意ください。
StackPanelクラス
子要素のコントロールを上から下、もしくは左から右に一列にずらっと並べます。
public class StackPanel : Panel
個人的にさらっとサンプル作るときとかは一番よく使います。
プロパティ
(Orientation) Orientation {get; set;}
子要素を並べる向きを取得、設定します。初期値はVertical(上から下)です。
OrientationがVerticalの場合はVerticalAlignmentの初期値がTopに、Horizontalの場合はHorizontalAlignmentの初期値はLeftになります。(明示的に指定して上書きは可能)
サンプルコード
// ボタンたくさん作る
var buttons = new Button[20];
for(int i=0; i<buttons.Length; i++) {
buttons[i] = new Button {
Text = (i+1).ToString(),
Width = 50,
Margin = 3,
};
}
// パネル作る
var panel = new StackPanel {
Orientation = Orientation.Horizontal,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
};
//配置
foreach(var button in buttons) {
panel.AddChild(button);
}
Chart.AddControl(panel);
こんな見た目になります。(わかりやすくするため、あえて小さめのチャートで実行させてます。)
20個のボタンが横一列に並びきらずに左右にはみ出てしまっています。
WrapPanelクラス
StackPanelとだいたい同じように縦か横にずらっと並べますが、子要素のコントロールを並べていって、一定以上の幅(高さ)を超えると折り返します。
StackPanelのようにはみ出すことがありません。また、子要素を配置するセルの大きさも指定できます。
public class WrapPanel : Panel
プロパティ
(Orientation) Orientation {get; set;}
子要素を並べる向きを取得、設定します。初期値はHorizontal(左から右)です。StackPanelと異なります。
なお、OrientationにかかわらずVerticalAlignmentの初期値はTop、HorizontalAlignmentの初期値はLeftです。
(int) ItemWidth {get; set;}
子要素を配置するスペース一つ当たりの横幅を取得、設定します。
(int) ItemHeight {get; set;}
子要素を配置するスペース一つ当たりの高さを取得、設定します。
サンプルコード
// ボタンたくさん作る
var buttons = new Button[20];
for(int i=0; i<buttons.Length; i++) {
buttons[i] = new Button {
Text = (i+1).ToString(),
Width = 50,
Margin = 3,
};
}
// パネル作る
var panel = new WrapPanel {
Orientation = Orientation.Horizontal,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
ItemWidth = 100,
ItemHeight = 30,
};
//配置
foreach(var button in buttons) {
panel.AddChild(button);
}
Chart.AddControl(panel);
こんな見た目になります。
ちなみに先ほどのコードのStackPanel→WrapPanelに変更し、ItemWidthとItemHeightの記述を加えただけです。
ItemWidthとItemHeightを指定したため、先ほどよりも余裕をもって並べられており、チャート右端で自動的に折り返しています。
各ボタンの幅はButtonのWidthで指定した通りで、ItemWidthに合わせて余白をあけて並んでいますが、ボタンの高さは指定していないため、ItemHeightに合わせて引き伸ばされます。
なお、WrapPanelではButton側でHorizontalAlignmentやVerticalAlignmentを設定してあげれば与えられたスペース内での配置調整が可能です。
DockPanelクラス
子要素内のDockプロパティでコントロールをどっち方向に詰め込むか指定して配置します。
public class DockPanel : Panel
プロパティ
(bool) LastChildFill {get; set;}
最後に配置された子要素で残りのスペースを埋め尽くすかどうかを取得、設定します。
サンプルコード
// ボタンたくさん作る
var buttons = new Button[20];
for (int i = 0; i < buttons.Length; i++) {
buttons[i] = new Button {
Margin = 3,
Dock = (Dock)(i%4),
Text = (i + 1).ToString() + ":" + ((Dock)(i % 4)).ToString(),
};
}
// パネル作って配置
var panel = new DockPanel {
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center,
};
foreach (var button in buttons) {
panel.AddChild(button);
}
Chart.AddControl(panel);
子要素ボタンのDockプロパティ設定のところがわかりにくいかもしれませんが、一つ目がLeft、2つ目がTop、3つ目がRight、4つ目がBottom、5つ目がLeft・・・と順番に設定してると思ってください。
こうなります。ぐるぐる~。
ボタン番号の後ろに表示されてるのがDockプロパティの値です。DockPanelという四角い箱に、1から順にDockで指定された方向に詰め込んでいった感じです。・・・伝わりますでしょうか。
順番に配置していくとこんな感じです。なお、別にcAlgo特有のものではなく、C#WPFのDockPanelと考え方は同じですのでわからない場合は検索してみてください。(丸投げ)
関連する列挙型
Orientation列挙型
StackPanelとWrapPanelがプロパティとして持ち、並べる方向を表します。
Horizontal | 横方向 |
Vertical | 縦方向 |
Dock列挙型
DockPanelで詰め込む方向を表します。コントロール子要素側(ControlBaseクラス)がプロパティとして持ちます。このプロパティはDockPanelに配置されたときのみ有効です。
Top | 上方向 |
Bottom | 下方向 |
Left | 左方向 |
Right | 右方向 |
Canvasで作った発注パネルを作り直す
Canvasのサンプルコードで簡単な発注パネルを作りました。
-
Canvas【cAlgoAPI】
絵を描くように自由にレイアウト コントロールのコンテナとしてCanvasを使えば自分で座標を指定してコントロールを配置することができるため、ピクセル単位で位置調整をする必要がある場合や、コントロールを ...
続きを見る
Canvasでのレイアウト設定部分はこんな感じでした。
// ボリュームテキストボックス
var volume = new TextBox {
Text = "1000",
Left = 10,
Top = 10,
Width = 90,
Height = 20,
};
//売買ボタン
var buy = new Button {
Text = "Buy",
Width = 40,
Height = 20,
Left = 10,
Top = 40,
};
var sell = new Button {
Text = "Sell",
Width = 40,
Height = 20,
Left = 60,
Top = 40,
};
//canvas作って配置
var canvas = new Canvas {
BackgroundColor = Color.White,
Width = 110,
Height = 70,
};
canvas.AddChild(volume);
canvas.AddChild(buy);
canvas.AddChild(sell);
Chart.AddControl(canvas);
これを今回説明したPanelで作り直してみます。
DockPanelバージョン
こうなります。(Canvas記事サンプルコードのレイアウト部分だけこれに入れ替えれば動きます)
// ボリュームテキストボックス
var volume = new TextBox {
Text = "1000",
Margin = 5,
Dock = Dock.Top,
};
//売買ボタン
var buy = new Button {
Text = "Buy",
Margin = 8,
Dock = Dock.Left,
};
var sell = new Button {
Text = "Sell",
Margin = 8,
Dock = Dock.Right
};
//panel作って配置
var panel = new DockPanel {
BackgroundColor = Color.White,
Width = 110,
Height = 70,
};
panel.AddChild(volume);
panel.AddChild(buy);
panel.AddChild(sell);
Chart.AddControl(panel);
見た目。
厳密には少し違いますが、だいたい同じです。子要素ではサイズも位置も自動調整に任せて、MarginとDockだけ指定してるところがポイントです。コード量も減ってますし、ちょっとしたレイアウト調整がこっちの方が圧倒的に楽になります。
StackPanel、WrapPanelバージョン
おおむね同じですが。
// ボリュームテキストボックス
var volume = new TextBox {
Text = "1000",
Margin = 5,
};
//売買ボタン
var buy = new Button {
Text = "Buy",
Margin = 8,
};
var sell = new Button {
Text = "Sell",
Margin = 8,
};
//panel作って配置
var panel = new StackPanel {
BackgroundColor = Color.White,
Width = 110,
Height = 70,
};
var buttonPanel = new WrapPanel();
buttonPanel.AddChild(buy);
buttonPanel.AddChild(sell);
panel.AddChild(volume);
panel.AddChild(buttonPanel);
Chart.AddControl(panel);
DockPanelバージョンとほぼ同じですが、子要素のDock指定がなくなって、配置部分ではPanelを2つ用意して組み合わせています。見た目は同じ。
コードではStackPanelとWrapPanelを使ってますが、たいした意味はありません。(Orientation指定を省略したかっただけ。)両方ともStackPanelもしくはWrapPanelでも構いません。
いずれにしても、Canvasで作った場合と比べてすっきりした記述になる上、いじってみた人はレイアウト調整もやりやすくなってるのがわかると思います。基本的にはこれら3つのPanelを利用しましょう。