谢谢@CydrickT,这很有帮助。在将其应用于带有FormBorderStyle
ofFixedDialog
和 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;
}
}
}
}