我正在尝试创建一个自定义 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;
}
}
所以我的主要问题是如何解决文本重绘问题?
此外,我对上述代码还有一些其他问题/评论:
起初,文本显示了两次,一次在默认位置,一次在旋转位置。我认为这是因为在
base.OnPaint
调用该方法时首先绘制文本。如果是这种情况,我该如何防止最初绘制文本?我的解决方案是在使用布尔值调用之前覆盖文本字符串并清除它
base.OnPaint
,这不是我特别满意的解决方案。我应该在最后处理 PaintEventArgs
e.dispose
吗?我想我不确定 PaintEventArgs 对象是如何处理的。
提前致谢!
附言。这是我的第一篇文章/问题,所以如果我无意中忽略了一些礼仪或规则,我提前道歉。