Comportamento estranho na FormBorderStyle entre fixo e dimensionável
Pergunta
Eu criei um formulário de teste simples com FormBorderStyle = FixedToolWindow por padrão e acrescentou um botão que alterna entre FixedToolWindow e SizableToolWindow na imprensa mouse.
Mudar o FormBorderStyle entre estes dois parece produzir um efeito estranho que está causando uma série de questões sobre o meu pedido. O problema é que a janela parece mudar de tamanho e eu não posso ter isso. Eu só quero mudar a beira, eu preciso do tamanho do formulário para permanecer o mesmo.
Por exemplo, aqui está o código do botão:
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;
}
}
E a depuração Eu uso este:
private void Settings_SizeChanged(object sender, System.EventArgs e) {
System.Diagnostics.Debug.WriteLine(this.Size);
}
E aqui está a saída quando eu pressionar o botão interruptor:
SWITCHING: FIXED -> SIZABLE
{Width=373, Height=169}
{Width=383, Height=179}
SWITCHING: SIZABLE -> FIXED
{Width=383, Height=179}
{Width=373, Height=169}
Como posso corrigir esse comportamento? E por "correção", quer dizer, impedir que isso aconteça, se possível. Eu quero ser capaz de especificar o meu tamanho forma e permanecer assim, não importa o tipo de estilo de borda.
Além disso, uma solução por subclasse a classe de formulário seria a solução perfeita para mim no caso de alguém como quaisquer ideias para resolver este problema com tal método a.
EDIT:
Fiz um pequeno vídeo para demonstrar o problema. O primeiro teste revela que o tamanho da forma na verdade não mudam (visualmente), apenas a localização da forma muda um pouco; mas os valores para a propriedade Tamanho fazer a mudança, como você pode ver na saída de depuração. O segundo teste que você verá na saída de depuração que a forma Tamanho valores de propriedade mudança e o próprio tamanho da janela também irá mudar.
Por favor, veja aqui:
http://screencast.com/t/0vT1vCoyx2u
Solução
Seu problema é com a Localização mudança, não o tamanho. Isto resolve o problema de código visto no vídeo.
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;
}
Parece-me que a questão da forma processada em movimento quando se alterna entre esses dois borderstyles é um bug no DWM.
Outras dicas
Eu suspeito que o que está acontecendo é que o Windows Forms é manter o tamanho do cliente (ou seja, área interna) o mesmo, enquanto as alterações de tamanho de fronteira. Isso geralmente é uma coisa boa porque garante que a janela ainda pode caber corretamente o conteúdo que você colocou nele.
Se você quiser manter as mesmas dimensões exteriores, você pode trabalhar em torno dele, salvando o tamanho de uma variável antes de alterar o tipo de borda, e depois restaurá-lo de volta. Eles vão provavelmente uma ligeira oscilação, apesar de tudo.
Esta funcionou bem para mim:
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;
}
Eu tive esse mesmo problema. O tamanho do cliente muda quando você definir o FormBorderStyle mas não parecem ter colocado na propriedade ClientRectangle imediatamente. O código acima listados quase funcionou para mim, mas, em vez de apenas o tamanho da loja, certifique-se de loja ClientSize. Claro que, no exemplo acima, talvez "este" era uma referência ao ClientSize - Eu não tinha certeza. Comprar qualquer maneira, isso funcionou para mim:
_frmFilter.Height = 300 _size Dim Como Size = .ClientSize _frmFilter.FormBorderStyle = FormBorderStyle.FixedToolWindow _frmFilter.ClientSize = _size