WinForms 按钮:Autosize Maximumsize

WinForms Button: Autosize Maximumsize

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

我看到的是,Button 的宽度受 MaximumSize 属性 的限制,但是当发生文本换行时,Button 的高度不会自动调整为换行文本的高度。这个问题有解决办法吗?


我也试过像这样手动调整按钮的大小:

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 填充 + ??????


几个小时后...

我来到这个版本,似乎工作得很好。

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

按钮的初始高度好像是borders + font的高度。所以我计算了边框减去button.Height-button.font.Height.

据汉斯说,我现在用的是TextRenderer.MeasureText。我在未启用 VisualStyles 的情况下对其进行了测试,并且运行良好。对此有何评论?

您应该通过在文本中添加换行符来控制换行符。自动换行不适用于单独的空格:

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

或者:

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

如果您希望自动换行,您可以尝试使用 TextMeasure 来确定文本所需的高度,然后相应地设置按钮的高度,但这可能需要额外注意..

但我建议考虑改用标签。对于 Label,包装是开箱即用的。具有不同大小的巨大按钮是非标准 UI 元素。

有一个正确的方法,但它不是很微妙。从ButtonRenderer class 源代码逆向工程,绘制按钮文本的Winforms class,必须使用TextRenderer class 来测量文本。并且您必须使用 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);
    }

没有针对极端情况进行广泛测试,不能说我推荐这个。

按钮的初始高度好像是borders + font的高度。所以我计算了边框减去button.Height-button.font.Height。 (看我原版的最后一块post)

这也适用于 VisualStyles enabled/disabled。