2008-08-11 35 views
38

Tôi đang sử dụng lớp .NETCF (Windows Mobile) Graphics và phương pháp DrawString() để hiển thị một ký tự đơn lẻ cho màn hình.Đầu ra văn bản trung tâm từ Graphics.DrawString()

Vấn đề là tôi không thể làm cho nó được căn giữa đúng cách. Không có vấn đề gì tôi đặt cho tọa độ Y của vị trí của chuỗi render, nó luôn luôn đi ra thấp hơn đó và lớn hơn kích thước văn bản lớn hơn Y bù đắp.

Ví dụ, ở kích thước văn bản 12, bù đắp khoảng 4, nhưng ở 32 bù đắp khoảng 10

Tôi muốn các nhân vật theo chiều dọc mất hầu hết các hình chữ nhật nó đang được rút ra trong và được làm trung tâm theo chiều ngang. Đây là mã cơ bản của tôi. this là tham khảo các điều khiển người dùng nó được rút ra trong.

Graphics g = this.CreateGraphics(); 

float padx = ((float)this.Size.Width) * (0.05F); 
float pady = ((float)this.Size.Height) * (0.05F); 

float width = ((float)this.Size.Width) - 2 * padx; 
float height = ((float)this.Size.Height) - 2 * pady; 

float emSize = height; 

g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular), 
      new SolidBrush(Color.Black), padx, pady); 

Vâng, tôi biết có sự kiểm soát nhãn mà tôi có thể sử dụng để thay thế và thiết lập các trung với điều đó, nhưng tôi thực sự cần phải làm điều này bằng tay với Graphics lớp học.

Trả lời

13

Thông qua một sự kết hợp của những gợi ý tôi, tôi đến với điều này:

private void DrawLetter() 
    { 
     Graphics g = this.CreateGraphics(); 

     float width = ((float)this.ClientRectangle.Width); 
     float height = ((float)this.ClientRectangle.Width); 

     float emSize = height; 

     Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular); 

     font = FindBestFitFont(g, letter.ToString(), font, this.ClientRectangle.Size); 

     SizeF size = g.MeasureString(letter.ToString(), font); 
     g.DrawString(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0); 

    } 

    private Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize) 
    { 
     // Compute actual size, shrink if needed 
     while (true) 
     { 
      SizeF size = g.MeasureString(text, font); 

      // It fits, back out 
      if (size.Height <= proposedSize.Height && 
       size.Width <= proposedSize.Width) { return font; } 

      // Try a smaller font (90% of old size) 
      Font oldFont = font; 
      font = new Font(font.Name, (float)(font.Size * .9), font.Style); 
      oldFont.Dispose(); 
     } 
    } 

Cho đến nay, công trình này một cách hoàn hảo.

Điều duy nhất tôi thay đổi là chuyển cuộc gọi FindBestFitFont() sang sự kiện OnResize() để tôi không gọi nó mỗi khi tôi vẽ một lá thư. Nó chỉ cần được gọi khi kích thước điều khiển thay đổi. Tôi chỉ đưa nó vào chức năng để hoàn thành.

1

Dưới đây là một số mã. Điều này giả định bạn đang làm điều này trên một biểu mẫu, hoặc một UserControl.

Graphics g = this.CreateGraphics(); 
SizeF size = g.MeasureString("string to measure"); 

int nLeft = Convert.ToInt32((this.ClientRectangle.Width/2) - (size.Width/2)); 
int nTop = Convert.ToInt32((this.ClientRectangle.Height/2) - (size.Height/2)); 

Từ bài đăng của bạn, có vẻ như phần ClientRectangle (như bạn không sử dụng) là điều khiến bạn gặp khó khăn.

8

Để vẽ một văn bản làm trung tâm:

TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor, 
    TextFormatFlags.HorizontalCenter | 
    TextFormatFlags.VerticalCenter | 
    TextFormatFlags.GlyphOverhangPadding); 

Xác định kích thước phông chữ tối ưu để lấp đầy diện tích là khó khăn hơn một chút. Một linh hồn làm việc mà tôi tìm thấy là thử và lỗi: bắt đầu với một phông chữ lớn, sau đó lặp đi lặp lại đo chuỗi và thu nhỏ phông chữ cho đến khi nó phù hợp.

Font FindBestFitFont(Graphics g, String text, Font font, 
    Size proposedSize, TextFormatFlags flags) 
{ 
    // Compute actual size, shrink if needed 
    while (true) 
    { 
    Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags); 

    // It fits, back out 
    if (size.Height <= proposedSize.Height && 
     size.Width <= proposedSize.Width) { return font; } 

    // Try a smaller font (90% of old size) 
    Font oldFont = font; 
    font = new Font(font.FontFamily, (float)(font.Size * .9)); 
    oldFont.Dispose(); 
    } 
} 

Bạn muốn sử dụng điều này như:

Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags); 
// Then do your drawing using the bestFitFont 
// Don't forget to dispose the font (if/when needed) 
+0

cảm ơn bạn đã cho thấy cách khác để vẽ nội dung nó thực sự giúp tôi với một vấn đề căn giữa quay ra TextRenderer.DrawText chính xác hơn sau đó một e.graphics.drawstring đơn giản cảm ơn rất nhiều, bỏ phiếu từ tôi :) –

54

Tôi muốn thêm một phiếu bầu khác cho đối tượng StringFormat. Bạn có thể sử dụng cách đơn giản để xác định "trung tâm, trung tâm" và các văn bản sẽ được rút ra ở trung tâm hình chữ nhật hoặc các điểm cung cấp:

StringFormat format = new StringFormat(); 
format.LineAlignment = StringAlignment.Center; 
format.Alignment = StringAlignment.Center; 

Tuy nhiên có một vấn đề với điều này trong CF. Nếu bạn sử dụng Trung tâm cho cả hai giá trị thì nó sẽ tắt TextWrapping.Không có ý tưởng tại sao điều này xảy ra, nó dường như là một lỗi với CF.

40

Để sắp xếp một văn bản sử dụng như sau:

StringFormat sf = new StringFormat(); 
sf.LineAlignment = StringAlignment.Center; 
sf.Alignment = StringAlignment.Center; 
e.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf); 

Xin lưu ý rằng các văn bản ở đây là liên kết trong giới hạn nhất định. Trong ví dụ này, đây là ClientRectangle.

+0

Chris's giải pháp là tuyệt vời. BTW nếu bạn muốn đặt ở trung tâm của ngang, nhưng dọc ở bất kỳ vị trí: e.Graphics.DrawString ("My String", this.Font, Brushes.Black, e.CellBounds.Width/2, y, sf); // y là vị trí dọc – camino

Các vấn đề liên quan