Странное поведение в FormBorderStyle между фиксированным и значительным

StackOverflow https://stackoverflow.com/questions/855673

  •  21-08-2019
  •  | 
  •  

Вопрос

Я создал простую тестовую форму с 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top