Я пытаюсь создать собственный элемент управления кнопки 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.
Заранее спасибо!
Пс. Это мой первый пост/вопрос, поэтому заранее извиняюсь, если случайно проигнорировал какой-то этикет или правила.