カスタムコントロール(その2)
簡単なので良く使う手だが、スクロールバーの変移値により、コントロールのクライアント領域座標のY軸を変更しつつ描画、つまりスクロールしている様を描画するのに、以下のようなコードを片を書くのだが、
vScrollBar.ValueChanged +=
delegate(object sender, EventArgs e)
{
this.Invalidate();
};
〜略〜
protected override void OnPaint(PaintEventArgs e)
{
Graphics gr = e.Graphics;
gr.PageUnit = GraphicsUnit.Pixel;
gr.Clear(this.BackColor);
gr.TranslateTransform(0, (vScrollBar.Value * -1)); //ここがスクロールして見えるミソ
//ボタンの描画
ButtonRenderer.DrawButton(gr, new Rectangle(0, 0, buttonSize, buttonSize), PushButtonState.Default);
//テキストの描画
TextRenderer.DrawText(gr, "スクロールするぜ", this.Font, new Point(buttonSize, 0), SystemColors.ControlText);
}
今回、VisualStyleを摘要したいこともあって、初めてVisualStyleRenderer系とGDI系のクラスで書いたのだが、これだと、描画したボタンはスクロールバーの変移に合わせてスクロールするのものの、文字は変換された座標が摘要されず、置いてけぼりになってしまう。(これはこれで、見た目が面白いので何かに使えそうなのだが)
GDIのレンダラは使えないな、とかぶつぶつ文句を並べていたのだが、TextRenderer.DrawTextメソッドでTextFormatFlags列挙体がパラメタに指定できることを、はたと思い出して調べてみると、ちゃんとあった。
TextFormatFlags 列挙体
メンバ
PreserveGraphicsTranslateTransform
Graphics で指定された変換を維持します。Graphics である IDeviceContext を受信するメソッドだけに適用されます。
このパラメタを指定することで、文字列も変換された座標に描画された。
//テキストの描画 TextRenderer.DrawText(gr, "スクロールするぜ", this.Font, new Point(buttonSize, 0), SystemColors.ControlText, TextFormatFlags.PreserveGraphicsTranslateTransform );
ボタンは何も指定しなくとも変換座標が反映されるのに、テキストの描画時は明示的に指定しないと反映されないのは何か狙いがあるのだろうか。