WinForms按钮:自动调整最大尺寸

本文关键字:调整 按钮 WinForms | 更新日期: 2023-09-27 18:04:37

我想添加按钮到FlowLayoutPanel。按钮可能包含较长的文本,单词之间有空格。按钮是Autosize=true和AutoSizeMode = AutoSizeMode. growandshrink。此外,我将MaximumSize属性设置为(maxwidth,0)。Maxwidth是面板的宽度。这样按钮就不会长得太宽。

我看到的是,按钮的宽度受到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;
}

似乎初始按钮的高度是边框+字体的高度。所以我计算了边框减去button.Height-button.font.Height.

根据Hans的说法,我现在使用TextRenderer.MeasureText。我在没有启用VisualStyles的情况下测试了它,它工作得很好。对此有什么评论吗?

WinForms按钮:自动调整最大尺寸

有一个合适的方法,但它并不是非常微妙。从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);
    }

没有广泛测试的角落的情况下,不能说我建议这样做。

似乎初始按钮的高度是边框+字体的高度。所以我计算了边框减去button。height -button。font。height。(见我原来的文章的最后一块)

您应该通过在文本中添加换行符来控制换行符。自动文本换行不能单独处理空格:

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

或:

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

如果你想获得自动换行,你可以尝试使用TextMeasure来确定文本所需的高度,然后相应地设置按钮的高度,但这可能需要一些额外的注意。

但是我建议考虑使用标签代替。对于标签,包装在盒子外工作。不同大小的巨大按钮是非标准的UI元素。