Странное поведение в FormBorderStyle между фиксированным и значительным
Вопрос
Я создал простую тестовую форму с FormBorderStyle =FixedToolWindow по умолчанию и добавил кнопку, которая будет переключаться между фиксированнымToolWindow и 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 формы изменяются, а также изменяется размер самого окна.
Пожалуйста, посмотрите здесь:
http://screencast.com/t/0vT1vCoyx2u
Решение
Ваша проблема связана с изменением местоположения, а не размера.Этот код решает проблему, показанную на видео.
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;
}
Мне кажется, что проблема перемещения отображаемой формы при переключении между этими двумя стилями границ является ошибкой в DWM.
Другие советы
Я подозреваю, что происходит то, что Windows Forms сохраняет размер клиента (т.внутренняя область) то же самое при изменении размера границы.В целом это хорошо, потому что это гарантирует, что окно по-прежнему сможет правильно разместить содержимое, которое вы в него поместили.
Если вы хотите сохранить те же внешние размеры, вы можете обойти эту проблему, сохранив размер в переменной перед изменением типа границы, а затем восстановив его обратно.Хотя они, вероятно, будут слегка мерцать.
Это сработало для меня:
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;
}
У меня была такая же проблема.Размер клиента изменяется, когда вы устанавливаете FormBorderStyle, но, похоже, он не сразу помещается в свойство clientrectangle.Приведенный выше код почти сработал для меня, но вместо того, чтобы просто хранить размер, обязательно сохраняйте размер клиента.Конечно, в приведенном выше примере, возможно, «это» было ссылкой на размер клиента — я не был уверен.В любом случае купите, мне помогло:
_frmFilter.Высота = 300 Dim _size Как Размер =.ClientSize _frmFilter.FormBorderStyle = FormBorderStyle.FixedToolWindow _frmFilter.ClientSize = _size