2014-10-01 85 views
1

我正在编写自己的控件库。我正在处理复选框控件,并且我需要帮助的最后一件事情是绘制与文本相关的复选框。我有一个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); 
     } 
    } 

一个解决方案是完全带走财产,我想。但这并不理想。另一个,我想做一个矩形,其中包含复选框以及文本,并相应地移动矩形,但我不知道如何实现。谢谢你的帮助!这里有一个画面,可能有助于说明问题:

+0

你为什么不使用* e.ClipRectangle *? – 2014-10-01 20:09:00

+0

“秘密”是*从不*硬编号码。当太阳正在闪闪发光时,10,12和14只是快乐的数字,并且你的背部有风。你有DisplayRectangle和Font.Height。变量。 – 2014-10-01 22:17:52

+0

@HansPassant否,无论文本/控件的位置/大小/字体/任何内容,复选框的_size_都是_always_将变为12x12,并且复选框的_fill size_将变为10,10。 14是唯一适用于你的建议。 – Minato 2014-10-01 22:26:51

回答

0

而不是任何用于你可以使用这个扩展我写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; 
} 

您可以使用此扩展不仅仅用于绘制字符串,当需要对齐需要在矩形内绘制的任何东西时,可以使用此扩展。

但在你的情况,你会做这样的事情:

g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), AlignDrawingPoint(g.MeasureString(this.Text, this.Font).ToSize(), this.ClientRectangle, this.TextAlign));