2013-08-06 5 views
5

Есть ли способ адаптировать размер формы к размеру ее заголовка/текста подписи?Адаптировать размер формы к тексту заголовка в C#

Например, официальный C# Message Box формы приспособится к размеру его текст заголовка (Обратите внимание на Lorem Ipsum):

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

Thanks @CydrickT, это было полезно. У меня есть некоторые изменения, которые были необходимы при применении этого к окну с FormBorderStyle из FixedDialog, и если ControlBox == false на форме (нужно попробовать поймать, чтобы обработать ошибочную ошибку).

Также, несмотря на то, что иконка указана, некоторые FormBorderStyle не отображают их (хотя ShowIcon == true, в котором ваш код основан на некоторой логике), поэтому эта версия кода настраивается для этого.

Я также добавил новое частное свойство, которое содержит минимальную ширину окна, установленного в конструкторе, до минимальной ширины, если она указана, или ширина времени проектирования, если нет. Это позволяет сократить ширину окна, если он изменит свой текст (заголовок) в коде, а затем отобразит форму.

Я добавил текст измененного метода для текста формы: , так что в любое время, когда текст заголовка формы изменяется, изменяется ширина формы (опять же, при повторном использовании экземпляра формы). Конечно, разработчику формы нужно было бы установить это для события 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; 
      } 
     } 
    } 
}