絵を描くように自由にレイアウト
コントロールのコンテナとしてCanvasを使えば自分で座標を指定してコントロールを配置することができるため、ピクセル単位で位置調整をする必要がある場合や、コントロールを少しだけ重ねて配置したい場合に使うことができます。
Canvasクラス
子要素内で指定された座標にコントロールを配置します。
public class Canvas : Panel
個別に座標指定する必要があるため、ちょっとしたレイアウト変更がやりにくく、しかもチャートサイズ変更時の挙動も微妙なため、実は使う機会はさほど多くないです。
プロパティおよびメソッド
ControlBase, Panelのプロパティとメソッド
このクラス特有のプロパティやメソッドはありません。重要なのはこのCanvasからAddChild()された場合のみ、子要素コントロールのLeft、Topプロパティが有効ということくらいです。
配置する座標は子要素側のLeft、Topプロパティで設定する、と覚えておいてください。
サンプルコード
表示させるだけじゃつまらないので簡単な発注機能作ってみました。cBotを新規作成して本体クラス直下にコピペしてみてください。(ボタン押すと発注入っちゃうのでリアル口座でやらないように注意!)
なおエラー処理などは最低限ですので、実際に使う場合には手を加えてください。
double _volume;
protected override void OnStart() {
_volume = Symbol.VolumeInUnitsMin;
// ボリュームテキストボックス
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);
//コントロールイベント
volume.TextChanged += t => {
if (double.TryParse(t.TextBox.Text, out _volume)) {
_volume = Symbol.NormalizeVolumeInUnits(_volume);
} else {
_volume = Symbol.VolumeInUnitsMin;
}
};
buy.Click += _ => ExecuteMarketOrder(TradeType.Buy, SymbolName, _volume);
sell.Click += _ => ExecuteMarketOrder(TradeType.Sell, SymbolName, _volume);
}
ちなみに見た目はこんな感じです。チャートのど真ん中に表れます。位置を変えたい場合はCanvasでHorizontalAlignmentとVerticalAlignmentを指定してあげてください。
Canvasオブジェクト自体ではたいしたことしてません、背景色とサイズ指定してAddChildしてるだけです。繰り返しますが、ポイントは位置指定は子要素側で行うというところ。
Left=とかTop=というのがすべてcanvas内での位置指定部部です。Canvasの左上を(0,0)として座標を指定します。ちなみにLeft,TopプロパティはCanvas以外に配置するとき設定しても意味ありません。Canvasに配置するときだけ使われるプロパティです。
このコードをいじって細かなレイアウト変更をやってみるとCanvasがあまり使われない理由がわかると思います。とにかく面倒なんです。そもそもプログラムコード上に生の数字がこんなに出てくること自体好ましくありません。
よっぽど繊細に位置を指定したいなど、特別な理由がない限りは後で紹介するStackPanelやDockPanelを組み合わせてGUIを構築することをおすすめします。
ポイント
canvas(Panel)側ではBackgroundColorを設定せずにBorder側で見た目をすべて設定してChildにCanvas(Panel)を設定することで見た目を整えることができます。