我默认使用FormBorderStyle = FixedToolWindow创建了一个简单的测试表单,并添加了一个按钮,该按钮将在鼠标按下时在FixedToolWindow和SizableToolWindow之间切换。
在这两者之间切换FormBorderStyle似乎会产生一种奇怪的效果,这会导致我的应用程序出现很多问题。问题是窗口似乎改变了大小,我不能拥有它。我只想更改边框,我需要保持相同的表单大小。
例如,这是按钮代码:
private void button1_Click(object sender, System.EventArgs e) {
if(FormBorderStyle == FormBorderStyle.FixedToolWindow) {
System.Diagnostics.Debug.WriteLine("SWITCHING: FIXED -> SIZABLE");
FormBorderStyle = FormBorderStyle.SizableToolWindow;
} else {
System.Diagnostics.Debug.WriteLine("SWITCHING: SIZABLE -> FIXED");
FormBorderStyle = FormBorderStyle.FixedToolWindow;
}
}
要调试我使用它:
private void Settings_SizeChanged(object sender, System.EventArgs e) {
System.Diagnostics.Debug.WriteLine(this.Size);
}
这是按下开关按钮时的输出:
SWITCHING: FIXED -> SIZABLE
{Width=373, Height=169}
{Width=383, Height=179}
SWITCHING: SIZABLE -> FIXED
{Width=383, Height=179}
{Width=373, Height=169}
如何解决此问题?通过“修复”,我的意思是,如果可能的话,防止这种情况发生。我希望能够指定我的表单大小并保持这样,无论边框样式的类型如何。
此外,通过继承Form类的解决方案对我来说是完美的解决方案,以防任何人想要用这样的方法来解决这个问题。
修改
我做了一个小视频来演示这个问题。第一个测试显示表单大小实际上没有变化(视觉上),只有表单的位置稍有变化;但正如您在调试输出中看到的那样,Size属性的值会发生变化。您将在调试输出中看到第二个测试,即表单Size属性值更改,窗口大小本身也将更改。
答案 0 :(得分:2)
您的问题是位置更改,而不是大小。此代码解决了视频中出现的问题。
private void Form1_DoubleClick(object sender, EventArgs e)
{
Point _location = this.PointToScreen(this.ClientRectangle.Location);
if (this.FormBorderStyle == FormBorderStyle.SizableToolWindow)
{
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
}
else
{
this.FormBorderStyle = FormBorderStyle.SizableToolWindow;
}
Point _newloc = this.PointToScreen(this.ClientRectangle.Location);
Size _diff = new Size(_newloc) - new Size(_location);
this.Location -= _diff;
}
在我看来,在这两种bordertyles之间切换时渲染表单移动的问题是DWM中的一个错误。
答案 1 :(得分:1)
我怀疑正在发生的事情是Windows窗体在边框大小改变时保持客户端大小(即内部区域)不变。这通常是一件好事,因为它确保窗口仍然可以正确地适合您放在其上的内容。
如果要保持相同的外部尺寸,可以在更改边框类型之前将尺寸保存到变量,然后将其恢复,从而解决此问题。不过,它们可能会略微闪烁。
答案 2 :(得分:0)
这对我来说很好:
private Size _size;
private void Form1_DoubleClick(object sender, EventArgs e)
{
_size = this.Size;
if (this.FormBorderStyle == FormBorderStyle.SizableToolWindow)
{
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
}
else
{
this.FormBorderStyle = FormBorderStyle.SizableToolWindow;
}
this.Size = _size;
}
答案 3 :(得分:0)
我有同样的问题。设置FormBorderStyle时客户端大小会更改,但它似乎不会立即放入clientrectangle属性。上面列出的代码几乎适合我,但不仅仅是存储大小,请确保存储客户端。当然,在上面的例子中,“this”可能是对客户端的引用 - 我不确定。无论如何,这对我有用:
_frmFilter.Height = 300 Dim _size As Size = .ClientSize _frmFilter.FormBorderStyle = FormBorderStyle.FixedToolWindow _frmFilter.ClientSize = _size