2013-08-06 100 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; 
      } 
     } 
    } 
}