[英]Content Alignment For Custom Control
I'm writing my own library of controls. 我正在编写自己的控件库。 I'm working on the check box control and one of the final things that I need help on is drawing the check box in relation to the text. 我正在使用复选框控件,需要帮助的最后一件事是绘制与文本相关的复选框。 I have a ContentAlignment property that can change where the text appears in the control, but I'm not sure how to adjust the check box in relation to that because I don't know how to get the location of the text in the control. 我有一个ContentAlignment属性,该属性可以更改文本在控件中的显示位置,但是我不确定如何调整复选框,因为我不知道如何获取文本在控件中的位置。
protected override void OnPaint(PaintEventArgs e)
{
Graphics canvas = e.Graphics;
canvas.SmoothingMode = SmoothingMode.HighQuality;
int x = 0;
int y = (int)(canvas.MeasureString(this.Text, this.Font).Height - 12) / 2;
switch (this.Style)
{
case E.CheckBoxStyle.Check:
canvas.DrawRectangle(new Pen(this.BorderColor), new Rectangle(x, y, 12, 12));
if (this.Checked)
canvas.DrawString("√", new Font("serif", 7f, FontStyle.Bold), Brushes.Black, 1f, 3f);
break;
case E.CheckBoxStyle.Round:
canvas.DrawEllipse(new Pen(this.BorderColor), new Rectangle(x, y, 12, 12));
if (this.Checked)
{
Rectangle region = new Rectangle(x + 1, y + 1, 10, 10);
canvas.FillEllipse(Functions.CreateGradient(region, this.FillColor, 90), region);
}
break;
case E.CheckBoxStyle.Square:
canvas.DrawRectangle(new Pen(this.BorderColor), new Rectangle(x, y, 12, 12));
if (this.Checked)
{
Rectangle region = new Rectangle(x + 1, y + 1, 10, 10);
canvas.FillRectangle(Functions.CreateGradient(region, this.FillColor, 90), region);
}
break;
}
if (!this.AutomaticSize)
{
StringFormat format = new StringFormat();
switch (this.Alignment)
{
case ContentAlignment.TopRight:
format.Alignment = StringAlignment.Far;
format.LineAlignment = StringAlignment.Near;
break;
case ContentAlignment.TopLeft:
format.Alignment = StringAlignment.Near;
format.LineAlignment = StringAlignment.Near;
break;
case ContentAlignment.TopCenter:
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Near;
break;
case ContentAlignment.MiddleRight:
format.Alignment = StringAlignment.Far;
format.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.MiddleLeft:
format.Alignment = StringAlignment.Near;
format.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.MiddleCenter:
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.BottomRight:
format.Alignment = StringAlignment.Far;
format.LineAlignment = StringAlignment.Far;
break;
case ContentAlignment.BottomLeft:
format.Alignment = StringAlignment.Near;
format.LineAlignment = StringAlignment.Far;
break;
case ContentAlignment.BottomCenter:
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Far;
break;
}
canvas.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), ClientRectangle, format);
}
else
{
canvas.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), 14f, 0f);
Size newSize = Size.Round(canvas.MeasureString(this.Text, this.Font));
this.Size = new Size(newSize.Width + 14, newSize.Height);
}
}
One solution is to take away the property completely, I suppose. 我想,一种解决方案是完全剥夺财产。 But that's not ideal. 但这并不理想。 Another, I thought make a rectangle that contains the check box as well as the text and to move that rectangle accordingly but I don't know how to implement that. 另一个,我认为制作一个包含复选框和文本的矩形,并相应地移动该矩形,但是我不知道如何实现。 Thanks for any help! 谢谢你的帮助! Here's a picture that might help show the problem: 这是一张有助于说明问题的图片:
Instead of any of the excessive code used for the switch statement you can use this extension I wrote: 您可以使用我编写的此扩展名来代替switch语句中使用的任何过多代码:
public static Point AlignDrawingPoint(this Graphics g, Size objectSize, Rectangle clientRectangle, ContentAlignment alignment)
{
int margin = 4;
Point center = new Point((clientRectangle.Width >> 1) - (objectSize.Width >> 1), (clientRectangle.Height >> 1) - (objectSize.Height >> 1));
int rightMargin = clientRectangle.Width - (objectSize.Width + margin);
int bottomMargin = clientRectangle.Height - (objectSize.Height + margin);
Point p = Point.Empty;
switch (alignment)
{
case ContentAlignment.TopLeft:
p = new Point(margin, margin);
break;
case ContentAlignment.TopCenter:
p = new Point(center.X, margin);
break;
case ContentAlignment.TopRight:
p = new Point(rightMargin, margin);
break;
case ContentAlignment.MiddleLeft:
p = new Point(margin, center.Y);
break;
case ContentAlignment.MiddleCenter:
p = new Point(center.X, center.Y);
break;
case ContentAlignment.MiddleRight:
p = new Point(rightMargin, center.Y);
break;
case ContentAlignment.BottomLeft:
p = new Point(margin, bottomMargin);
break;
case ContentAlignment.BottomCenter:
p = new Point(center.X, bottomMargin);
break;
case ContentAlignment.BottomRight:
p = new Point(rightMargin, bottomMargin);
break;
}
p.Offset(clientRectangle.X, clientRectangle.Y);
return p;
}
You can use this extension not just for drawing strings, you can use this extension when needing to align anything you need to draw within a rectangle. 您可以将此扩展名不仅用于绘制字符串,还可以在需要对齐矩形中需要绘制的任何内容时使用此扩展名。
But in your case you would do something like this: 但是在您的情况下,您将执行以下操作:
g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), AlignDrawingPoint(g.MeasureString(this.Text, this.Font).ToSize(), this.ClientRectangle, this.TextAlign));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.