我正在尝试创建一个自定义的Winforms按钮控件,允许通过“rotation”属性旋转按钮文本。我已经基本实现了它,但是它非常笨拙,我想知道正确的方法是什么。
特别是现在文本重绘的行为很奇怪。如果控件移出屏幕,然后缓慢移回,文本要么变得混乱(例如只画了一半),要么完全消失,直到鼠标移到上面。显然我做错了什么,但是无法弄清楚原因。
我继承了按钮控件并重写了其OnPaint方法。
以下是代码:
所以我的主要问题是如何解决文字重绘问题?
此外,对于上面的代码,我还有一些其他问题/评论:
1. 首先,文本会显示两次,一次是在其默认位置,另一次是在旋转位置。我想这是因为当调用
2. 我是否应该在结尾处使用
提前致谢!
附:这是我的第一个帖子/问题,所以如果我无意中忽略了一些礼节或规则,请您多多包涵。
特别是现在文本重绘的行为很奇怪。如果控件移出屏幕,然后缓慢移回,文本要么变得混乱(例如只画了一半),要么完全消失,直到鼠标移到上面。显然我做错了什么,但是无法弄清楚原因。
我继承了按钮控件并重写了其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;
}
}
所以我的主要问题是如何解决文字重绘问题?
此外,对于上面的代码,我还有一些其他问题/评论:
1. 首先,文本会显示两次,一次是在其默认位置,另一次是在旋转位置。我想这是因为当调用
base.OnPaint
方法时,文本首先被绘制。如果是这样,我该如何防止文本最初绘制?
我的解决方案是覆盖Text字符串,并在使用布尔值清除之前调用base.OnPaint
,但我并不满意这种解决方案。2. 我是否应该在结尾处使用
e.dispose
来处理PaintEventArgs?我猜我不太确定PaintEventArgs对象是如何处理的。提前致谢!
附:这是我的第一个帖子/问题,所以如果我无意中忽略了一些礼节或规则,请您多多包涵。