Центрирование вывода текста из Graphics.DrawString ()

Современные версии functools.wraps устанавливают исходную функцию в качестве атрибута __wrapped__ в создаваемых ими оболочках. (Можно найти в __closure__ вложенные функции, обычно используемые для этой цели, но можно использовать и другие типы.) Разумно ожидать, что любая оболочка будет следовать этому соглашению.

Альтернативой является наличие постоянной оболочки, которой можно управлять с помощью флага , чтобы его можно было включать и отключать, не удаляя и не восстанавливая его. Это имеет то преимущество, что оболочка может сохранять свое состояние (здесь кэшированные значения). Флаг может быть отдельной переменной (, например, , другой атрибут объекта, несущего упакованную функцию, если таковой имеется) или может быть атрибутом самой оболочки.

58
задан Ijas Ameenudeen 20 January 2019 в 13:53
поделиться

6 ответов

Через комбинацию предложений я добрался, я придумал это:

    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();
        }
    }

До сих пор, это работает безупречно.

единственная вещь, которую я изменил бы, состоит в том, чтобы переместиться, FindBestFitFont () звонят в событие OnResize() так, чтобы я не называл его каждым разом, когда я тяну букву. Это только нужно назвать, когда размер элемента управления изменяется. Я просто включал его в функцию для полноты.

19
ответ дан Adam Haile 24 November 2019 в 18:41
поделиться

Я хотел бы добавить другое голосование за объект StringFormat. Можно использовать это просто для определения "центра, центр" и текст будут привлечены централизованно в прямоугольнике или обеспеченных точках:

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

Однако существует одна проблема с этим в CF. При использовании Центра обоих значений тогда, он выключает TextWrapping. Никакая идея, почему это происходит, это, кажется, ошибка с CF.

78
ответ дан Marshal 24 November 2019 в 18:41
поделиться

Для выравнивания текста используют следующее:

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

Обратите внимание на то, что текст здесь выровненный в данных границах. В этом образце это - ClientRectangle.

55
ответ дан LPL 24 November 2019 в 18:41
поделиться

Нарисовать текст в центре:

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

Определение оптимального размера шрифта для заполнения области является немного более трудным. Одно рабочее решение, которое я нашел, является эмпирическим: запустите с крупного шрифта, тогда неоднократно измеряйте строку и уменьшайте шрифт, пока это не будет соответствовать.

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();
  }
}

Вы использовали бы это как:

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)
10
ответ дан dbkk 24 November 2019 в 18:41
поделиться

Можно использовать экземпляр эти StringFormat, объект передал в DrawString метод для центрирования текста.

См. Графика. Метод DrawString и Класс .

StringFormat
3
ответ дан Sergey Kolodiy 24 November 2019 в 18:41
поделиться

Вот некоторый код. Это предполагает выполнение этого на форме или 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));

Из Вашего сообщения, это походит на часть ClientRectangle (как в, Вы не используете его), то, что дает Вам трудность.

2
ответ дан TheSmurf 24 November 2019 в 18:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: