在C#中将表单的大小调整为其标题文本

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

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

普通消息框

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

其他形式

相反,在末尾添加省略号以适合设计器的“大小”属性中提到的大小。

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

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

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

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

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

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

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

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

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

谢谢@CydrickT,这很有帮助。 我将一些修改应用到一个FormBorderStyleFixedDialog的窗口,并且如果窗体上的ControlBox == false (需要try 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(); } ///  /// ///  ///  ///  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; } } } }