Как я могу узнать, когда текст System.Windows.Forms.GroupBox переносится на следующую строку? - PullRequest
3 голосов
/ 12 марта 2010

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

То, что я хотел бы сделать, это определить, если и когда текст переносится. В частности, я бы хотел определить, сколько дополнительной высоты занимает обернутый текст по сравнению с одной строкой. Таким образом, я могу переместить элементы управления GroupBox и настроить его высоту.

Изначально я думал, что сделаю это, вызвав метод CreateGraphics() GroupBox и используя Graphics для измерения строки. Как то так:

private void SetGroupBoxText(GroupBox grp, string text)
{
    const int somePadding = 10;

    Graphics g = grp.CreateGraphics();
    SizeF textSize = g.MeasureString(text, grp.Font);
    if (textSize.Width > (grp.Width - somePadding))
    {
        // Adjust height, etc.
    }
}

Проблема в том, что размер, сгенерированный g.MeasureString(text, grp.Font), кажется не точным. Я решил, что это не совсем точно, поместив достаточно одного символа, чтобы вызвать перенос, а затем измерив полученную строку.

Например, потребовалось 86 труб (|), пока не произошло обтекание. Когда я измерил эту строку, ее ширина была ~ 253. И понадобилось 16 заглавных букв W, чтобы вызвать перенос - его строка имела ширину ~ 164. Это были две крайности, которые я тестировал. Ширина моего GroupBox составляла 189. (a занимает 29 и имеет ширину ~ 180, O занимает 22 и имеет ширину ~ 189)

У кого-нибудь есть идеи? (взломать, WinAPI и т. д. приветствуются решения)

Ответы [ 3 ]

2 голосов
/ 12 марта 2010

Этот код был получен из ссылочного источника, он должен быть очень близок. Возвращает количество пикселей, добавленных к высоте текста, когда отображает более одной строки текста:

    public static int GetGroupboxTextHeightExtra(GroupBox box) {
        TextFormatFlags flags = TextFormatFlags.Default | TextFormatFlags.TextBoxControl | TextFormatFlags.WordBreak | TextFormatFlags.PreserveGraphicsTranslateTransform | TextFormatFlags.PreserveGraphicsClipping;
        Rectangle rc = new Rectangle(0, 0, box.Width - 2 * 7, box.Height);
        Size size;
        using (Graphics gr = Application.OpenForms[0].CreateGraphics()) {
            size = TextRenderer.MeasureText(gr, box.Text, box.Font, rc.Size, flags);
        }
        return size.Height - box.Font.Height;
    }
0 голосов
/ 12 марта 2010

Почему бы не использовать менеджер макетов для вашей проблемы? Компоновка менеджера компоновки управляет контейнером таким образом, который освобождает вас от выполнения этих вычислений. Вы можете найти менеджеров по расположению от таких поставщиков, как DevXpress и Syncfusion. Я думаю, что в .Net Framework есть менеджер компоновки.

0 голосов
/ 12 марта 2010

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

В большинстве случаев у вас не должно быть много текста в заголовке группового блока. Подумайте о том, чтобы добавить ярлык под групповой рамкой, который будет более детальным. Помните, что групповое поле предназначено для «группировки» аналогичных элементов управления. Таким образом, текст на самом поле группы должен быть минимальным и имитировать заголовок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...