私は、rotationプロパティを介してボタンテキストの回転を可能にするカスタムwinformsボタンコントロールを作成しようとしています。私はほとんどそれを機能させていますが、それは非常に厄介であり、これを行うための適切な方法を知りたいです。
特に現在、テキストの再描画は奇妙な動作をしています。コントロールを画面の外に移動してからゆっくりとテキストに戻すと、テキストがめちゃくちゃになるか(半分しか描画されないなど)、マウスを合わせるまで完全に消えます。明らかに私は何か間違ったことをしているが、何を理解することができない。
ボタンコントロールから継承し、OnPaintメソッドをオーバーライドしています。
コードは次のとおりです。
public class RotateButton : Button
{
private string text;
private bool painting = false;
public enum RotationType { None, Right, Flip, Left}
[DefaultValue(RotationType.None), Category("Appearance"), Description("Rotates Button Text")]
public RotationType Rotation { get; set; }
public override string Text
{
get
{
if (!painting)
return text;
else
return "";
}
set
{
text = value;
}
}
protected override void OnPaint(PaintEventArgs e)
{
painting = true;
base.OnPaint(e);
StringFormat format = new StringFormat();
Int32 lNum = (Int32)Math.Log((Double)this.TextAlign, 2);
format.LineAlignment = (StringAlignment)(lNum / 4);
format.Alignment = (StringAlignment)(lNum % 4);
int padding = 2;
SizeF txt = e.Graphics.MeasureString(Text, this.Font);
SizeF sz = e.Graphics.VisibleClipBounds.Size;
if (Rotation == RotationType.Right)
{
//90 degrees
e.Graphics.TranslateTransform(sz.Width, 0);
e.Graphics.RotateTransform(90);
e.Graphics.DrawString(text, this.Font, Brushes.Black, new RectangleF(padding, padding, sz.Height - padding, sz.Width - padding), format);
e.Graphics.ResetTransform();
}
else if (Rotation == RotationType.Flip)
{
//180 degrees
e.Graphics.TranslateTransform(sz.Width, sz.Height);
e.Graphics.RotateTransform(180);
e.Graphics.DrawString(text, this.Font, Brushes.Black, new RectangleF(padding, padding, sz.Width - padding, sz.Height - padding), format);
e.Graphics.ResetTransform();
}
else if (Rotation == RotationType.Left)
{
//270 degrees
e.Graphics.TranslateTransform(0, sz.Height);
e.Graphics.RotateTransform(270);
e.Graphics.DrawString(text, this.Font, Brushes.Black, new RectangleF(padding, padding, sz.Height - padding, sz.Width - padding), format);
e.Graphics.ResetTransform();
}
else
{
//0 = 360 degrees
e.Graphics.TranslateTransform(0, 0);
e.Graphics.RotateTransform(0);
e.Graphics.DrawString(text, this.Font, Brushes.Black, new RectangleF(padding, padding, sz.Width - padding, sz.Height - padding), format);
e.Graphics.ResetTransform();
}
painting = false;
}
}
だから私の主な質問は、テキストの再描画の問題をどのように修正できるかということです。
さらに、上記のコードについて他にもいくつか質問/コメントがあります。
最初は、テキストが2回表示されていました。1回はデフォルトの場所に、もう1回は回転した場所に表示されていました。これは、
base.OnPaint
メソッドが呼び出されたときにテキストが最初に描画されるためだと思います。この場合、テキストが最初に描画されないようにするにはどうすればよいですか?私の解決策は、ブール値を使用して呼び出す前に、テキスト文字列をオーバーライドしてクリアすること
base.OnPaint
です。これは、私が特に満足している解決策ではありません。最後にPaintEventArgsをで破棄する必要があり
e.dispose
ますか?PaintEventArgsオブジェクトがどのように処理されているのかわかりません。
前もって感謝します!
追伸 初めての投稿・質問ですので、エチケットやルールをうっかり無視してしまった場合は、あらかじめお詫び申し上げます。