2015-07-26 4 views
2

Я хочу добавить кнопки в FlowLayoutPanel. Кнопки могут содержать более длинные тексты с пробелами между словами. Кнопки: Autosize = true и AutoSizeMode = AutoSizeMode.GrowAndShrink. Кроме того, я устанавливаю свойство MaximumSize равным (maxwidth, 0). maxwidth - это ширина панели. Таким образом, кнопка не становится слишком широкой.Кнопка WinForms: Autosize Maximumsize

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


Я также попытался вручную проклейки кнопки так:

using (Graphics cg = this.CreateGraphics()) { 
SizeF size = cg.MeasureString(button.Text, button.Font, 200); 
    button.Width = (int)size.Width+20; 
    button.Height = (int)size.Height+20; 
    button.Text = someLongTextWithSpaces; 
} 

Но обратите внимание, что я добавил 20 к расчетному размеру. Он работает, но есть ли способ определить этот дополнительный размер? Может быть, 2x Padding + ?????


Через несколько часов ...

Я пришел к этой версии, которая, кажется, работает довольно хорошо.

using (Graphics cg = this.CreateGraphics()) { 
    var fmt = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak; 
    var prop = new Size(tableLayoutPanel1.Width - 20, 0); 
    var size = TextRenderer.MeasureText(button.Text, button.Font, prop, fmt); 

    int border = button.Height - button.Font.Height; 
    button.Width = (int)size.Width + border; 
    button.Height = (int)size.Height + border; 
    button.Text = someLongTextWithSpaces; 
} 

Похоже, что начальная высота кнопки - это границы + высота шрифта. Таким образом, я вычислил кнопку вычитания границы. Hightight button.font.Height.

Согласно Хансу, теперь я использую TextRenderer.MeasureText. Я тестировал его без включения VisualStyles, и он работал нормально. Любые комментарии по этому поводу?

+0

вместо 'maxwidth' (если вы вручную добавили этот номер) попробуйте этот' FlowLayoutPanel1.ClientRectangle.Width' (или, тем не менее, вы вызвали эту панель). .... например, в 'Form_Resize' поставить код:' Button1.MaximumSize = Новый размер (FlowLayoutPanel1.ClientRectangle.Width, 0) '(это код vb, пожалуйста, конвертируйте его в C#) .... Я думаю, это C# code: 'Button1.MaximumSize == new Size (FlowLayoutPanel1.ClientRectangle.Width, 0);' – nelek

+0

Я также устанавливаю MaximumSize вручную на фиксированное значение. Значение в порядке, только изменение размера по высоте не работает. Вы можете проверить это и в FormDesigner. Добавьте авторизованную кнопку с расширением/shring и более длинный текст с пробелами. Установите максимальную ширину, меньшую, чем текст. Ширина кнопки ограничена, но она не растет в высоту. – bebo

+0

Почему вы добавили +20? –

ответ

0

Кажется, что начальная высота кнопки - это границы + высота шрифта. Таким образом, я вычислил кнопку вычитания границы. Hightight button.font.Height. (См. Последний блок моего исходного сообщения)

Это также работает с включенными/отключенными VisualStyles.

0

Вы должны контролировать разрывы строк, добавляя символы новой строки в текст. Автоматический перенос текста не будет работать с одними пробелами:

button1.Text = "123232131232\r\nfgfdgfdgdfgdfgdf\r\nASDSADSDASD"; 

Или:

button1.Text = "123232131232" + Environment.NewLine + 
      "fgfdgfdgdfgdfgdf" + Environment.NewLine + "ASDSADSDASD"; 

Если вы не хотите получить автоматическую упаковку, вы можете попробовать использовать TextMeasure, чтобы определить высоту, необходимую для текста и затем соответствующим образом установите высоту кнопки, но это может потребовать дополнительного внимания.

Но я предлагаю вместо этого использовать ярлыки. Для ярлыка обертка работает из коробки. Огромные кнопки с различными размерами являются нестандартными элементами интерфейса.

2

Существует правильный способ, но это не совсем тонко. Обратно-инжиниринг из исходного кода класса ButtonRenderer, класса Winforms, который рисует текст кнопки, вы должны использовать класс TextRenderer для измерения текста. И вы должны использовать метод VisualStyleRenderer.GetBackgroundContentRectangle() для получения эффективных границ чертежа. Обратите внимание, что размер кнопки меньше размера кнопки из-за границы и поля, который зависит от выбранного визуального стиля.

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

private static void SetButtonSize(Graphics gr, Button button) { 
     VisualStyleElement ButtonElement = VisualStyleElement.Button.PushButton.Normal; 
     var visualStyleRenderer = new VisualStyleRenderer(ButtonElement.ClassName, ButtonElement.Part, 0); 
     var bounds = visualStyleRenderer.GetBackgroundContentRectangle(gr, button.Bounds); 
     var margin = button.Height - bounds.Height; 
     var fmt = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak; 
     var prop = new Size(bounds.Width, 0); 
     var size = TextRenderer.MeasureText(button.Text, button.Font, prop, fmt); 
     button.ClientSize = new Size(button.ClientSize.Width, size.Height - margin); 
    } 

    protected override void OnLoad(EventArgs e) { 
     using (var gr = this.CreateGraphics()) { 
      SetButtonSize(gr, this.button1); 
     } 
     base.OnLoad(e); 
    } 

Не тщательно протестированы для угловых случаев, не могу сказать, что я рекомендую это.

+0

Я создал новый способ расчета границы (см. Мой пост выше). Считаете ли вы, что это подходящий способ? По крайней мере, это сработало для меня и с включенным VisualStyles. – bebo

+0

Хмм, магические числа, подобные «20», никогда не являются хорошей идеей, они не срабатывают при изменении DPI видео. –

+0

Вы хотите сказать "20" в "tableLayoutPanel1.Width - 20"? Я просто не хочу, чтобы кнопка заполняла полную ширину таблицыLayoutPanel1. Хорошо, на самом деле расстояние между центрированной кнопкой заканчивается сторонами не 2x10, а 2x (10-границами). Поэтому, если граница не равна 10 или более, она должна соответствовать. Может быть, мне нужно использовать 2x (расчетная граница + что-то) и принять это вместо «20». – bebo

Смежные вопросы