6

有没有办法使表单的大小适应其标题/标题文本的大小?

例如,官方 C# 消息框表单将调整其标题文本的大小(注意lorem ipsum):

普通消息框

其他表单不会将其大小调整为标题文本的大小:

其他形式

取而代之的是,在末尾添加一个省略号以适合设计器的“尺寸”属性中提到的尺寸。

有没有办法让表格适应标题的大小而不是我们提到的大小?如果没有,有没有办法获取文本的完整长度,以便我们可以将其分配给表单?

我尝试使用设置表单的宽度

int topTextWidth =  TextRenderer.MeasureText(this.Text, this.Font).Width;
this.Width = topTextWidth;

this.Font显然是指另一种字体大小。

4

2 回答 2

8

对于那些想要完整答案的人,这里就是。

根据标题文本调整表单大小的实际行如下:

this.Width = TextRenderer.MeasureText(this.Text, SystemFonts.CaptionFont).Width + AllButtonsAndPadding;

AllButtonsAndPadding包含所有按钮(最小化、最大化和关闭)、窗口边框和图标的宽度。获取这些信息需要一些编码。这是一个调整自身大小的表单的完整示例,无论您放置什么按钮或图标。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace WindowAutoAdapt
{
public partial class Form1 : Form
{
    //A default value in case Application.RenderWithVisualStyles == false
    private int AllButtonsAndPadding = 0;
    private VisualStyleRenderer renderer = null;

    public Form1()
    {
        InitializeComponent();
        this.Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; //A big text in the title
        GetElementsSize();
        ResizeForm();
    }

    //This gets the size of the X and the border of the form
    private void GetElementsSize()
    {
        var g = this.CreateGraphics();

        // Get the size of the close button.
        if (SetRenderer(VisualStyleElement.Window.CloseButton.Normal))
        {
            AllButtonsAndPadding += renderer.GetPartSize(g, ThemeSizeType.True).Width;
        }

        // Get the size of the minimize button.
        if (this.MinimizeBox && SetRenderer(VisualStyleElement.Window.MinButton.Normal))
        {
            AllButtonsAndPadding += renderer.GetPartSize(g, ThemeSizeType.True).Width;
        }

        // Get the size of the maximize button.
        if (this.MaximizeBox && SetRenderer(VisualStyleElement.Window.MaxButton.Normal))
        {
            AllButtonsAndPadding += renderer.GetPartSize(g, ThemeSizeType.True).Width;
        }

        // Get the size of the icon.
        if (this.ShowIcon)
        {
            AllButtonsAndPadding += this.Icon.Width;
        }

        // Get the thickness of the left, bottom, 
        // and right window frame.
        if (SetRenderer(VisualStyleElement.Window.FrameLeft.Active))
        {
            AllButtonsAndPadding += (renderer.GetPartSize(g, ThemeSizeType.True).Width) * 2; //Borders on both side
        }
    }

    //This resizes the form
    private void ResizeForm()
    {
        this.Width = TextRenderer.MeasureText(this.Text, SystemFonts.CaptionFont).Width + AllButtonsAndPadding;
    }

    //This sets the renderer to the element we want
    private bool SetRenderer(VisualStyleElement element)
    {
        bool bReturn = VisualStyleRenderer.IsElementDefined(element);

        if (bReturn && renderer == null)
            renderer = new VisualStyleRenderer(element);
        else
            renderer.SetParameters(element);

        return bReturn;
    }
 }
 }
于 2013-08-07T16:05:02.380 回答
0

谢谢@CydrickT,这很有帮助。在将其应用于带有FormBorderStyleofFixedDialog和 ifControlBox == false在窗体上的窗口时,我需要进行一些修改(需要尝试 catch 来处理抛出的错误)。

此外,即使指定了图标,某些FormBorderStyle' 也不会显示它们(即使 ShowIcon == true 您的代码基于某些逻辑),因此此版本的代码会对此进行调整。

我还添加了一个新的私有属性,它将在构造函数中设置的窗口的最小宽度保存为最小宽度(如果已指定)或设计时宽度(如果未指定)。如果要在代码中更改其文本(标题)然后重新显示窗体,这将允许缩小窗口的宽度。

我为表单的文本添加了一个文本更改方法:Form1_TextChanged()因此,无论何时更改表单的标题文本,表单宽度都会调整(同样,如果重用表单实例)。表单的设计者当然需要为要使用的 Text Changed 事件进行设置。

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace WindowAutoAdapt
{
    public partial class Form1: Form
    {
        private int AllButtonsAndPadding = 10;//seems things are coming up about this amount short so.  . .
        private VisualStyleRenderer renderer = null;
        private int minWidth = 0;//will hold either the minimum size width if specified or the design time width of the form.

        public Form1()
        {
            InitializeComponent();

            //Capture an explicit minimum width if present else store the design time width.
            if (this.MinimumSize.Width > 0)
            {
                minWidth = this.MinimumSize.Width;//use an explicit minimum width if present.
            }
            else
            {
                minWidth = this.Size.Width;//use design time width
            }

            GetElementsSize();
            ResizeForm();
        }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Form1_TextChanged(object sender, EventArgs e)
    {
        GetElementsSize();
        ResizeForm();
    }

        //This gets the size of the X and the border of the form
        private void GetElementsSize()
        {
            var g = this.CreateGraphics();

            // Get the size of the close button.
            if (SetRenderer(VisualStyleElement.Window.CloseButton.Normal))
            {
                AllButtonsAndPadding += renderer.GetPartSize(g, ThemeSizeType.True).Width;
            }

            // Get the size of the minimize button.
            if (this.MinimizeBox && SetRenderer(VisualStyleElement.Window.MinButton.Normal))
            {
                AllButtonsAndPadding += renderer.GetPartSize(g, ThemeSizeType.True).Width;
            }

            // Get the size of the maximize button.
            if (this.MaximizeBox && SetRenderer(VisualStyleElement.Window.MaxButton.Normal))
            {
                AllButtonsAndPadding += renderer.GetPartSize(g, ThemeSizeType.True).Width;
            }

            // Get the size of the icon only if it is actually going to be displayed.
            if (this.ShowIcon && this.ControlBox && (this.FormBorderStyle == FormBorderStyle.Fixed3D || this.FormBorderStyle == FormBorderStyle.Sizable || this.FormBorderStyle == FormBorderStyle.FixedSingle))
            {
                AllButtonsAndPadding += this.Icon.Width;
            }

            // Get the thickness of the left and right window frame.
            if (SetRenderer(VisualStyleElement.Window.FrameLeft.Active))
            {
                AllButtonsAndPadding += (renderer.GetPartSize(g, ThemeSizeType.True).Width) * 2; //Borders on both side
            }
        }

        //This resizes the form
        private void ResizeForm()
        {
            //widen window if title length requires it else contract it to the minWidth if required.
            int newWidth = TextRenderer.MeasureText(this.Text, SystemFonts.CaptionFont).Width + AllButtonsAndPadding;
            if (newWidth > minWidth)
            {
                this.Width = newWidth;
            }
            else
            {
                this.Width = minWidth;
            }
        }

        //This sets the renderer to the element we want
        private bool SetRenderer(VisualStyleElement element)
        {
            try
            {
                bool bReturn = VisualStyleRenderer.IsElementDefined(element);
                if (bReturn && renderer == null)
                {
                    renderer = new VisualStyleRenderer(element);
                }
                else
                {
                    renderer.SetParameters(element);
                }
                return bReturn;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
于 2016-05-19T15:51:13.420 回答