2013-08-06 39 views
5

有没有办法将表单的大小调整为标题/标题文本的大小?将表单的大小调整为C#中的标题文本

例如,官方C#消息框的形式将调整其标题文本的大小(注意Lorem存有):

Normal Message Box

其他形式不会调整其大小到他们标题文本:

Other form

相反,省略号在结束时添加,以适应吨的“大小”属性中提到的尺寸他设计师。

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

我尝试使用

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

this.Font但显然指的是另一种字体大小设置形式的宽度。

+5

您可能想要使用'SystemFonts.CaptionFont'。还要记住,'Width'必须考虑边界,图标,最小化/最大化/关闭按钮以及它们之间的填充/边距。 – JosephHirn

+1

感谢您的提示。我知道C#中有很多方法可以知道X按钮的宽度以及它周围的填充。只要我知道答案,我会尽快回复。 – CydrickT

回答

7

对于那些想要一个完整的答案,在这里。

,根据字幕文本调整大小形式的实际线如下:

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

谢谢@CydrickT,这很有帮助。我有一些修改,当将这个应用到FormBorderStyleFixedDialog和如果ControlBox == false窗体上(需要尝试catch来处理抛出的错误)时,需要这样的修改。

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

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

我为表单的文本添加了一个文本更改方法:,以便随时更改表单的标题文本时,表单宽度会调整(如果重新使用表单实例,则会再次调整)。表单的设计者当然需要设置这个文字改变事件来使用。

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