2014-10-01 82 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));