27 04 2016
Ajustando o formulário dependendo da resolução no Windows Forms
Não sei se você lembra, mas, tinha uma época em que as resoluções dos monitores eram meio que “fixas“. Se você tinha um computador “mediano“, provavelmente a resolução dele era 800×600. Caso você tivesse um pouco mais de grana, o luxo era investir em uma placa de vídeo e monitor que suportasse 1024×780.
Hoje em dia isso não é mais a realidade. Com as placas de vídeo e monitores evoluindo rapidamente, em pouco tempo surge uma nova resolução, cada vez maior. 720p, 1080p e agora 4k. E isso sem falar nos problemas que o ajuste de DPI podem trazer para o nosso aplicativo!
Normalmente, os aplicativos WPF se comportam muito bem quando alteramos a resolução e DPI do Windows, uma vez que, por padrão, ele trabalha com contêineres de layout e unidades independentes de resolução (e não pixels). Porém, no Windows Forms não é muito difícil termos problema com alterações de resolução. Pensando nisso, resolvi escrever este artigo detalhando como podemos ajustar o formulário dependendo da resolução no Windows Forms.
Criando o projeto de exemplo
Para entendermos os problemas que uma alteração na resolução ou DPI podem trazer para aplicativos Windows Forms, vamos construir um novo projeto do tipo “Windows Forms Application“. Nesse projeto, altere o formulário para que ele fique parecido com a imagem abaixo:
Esse é o típico exemplo em que teremos problema se o usuário estiver trabalhando em uma resolução maior do que a que desenvolvemos o nosso sistema. Nesse caso, o usuário provavelmente tentará aumentar o tamanho do formulário (ou até mesmo maximizar a janela) e, como no Windows Forms os componentes têm tamanho fixo por padrão, eles continuarão com o seu tamanho original. Veja o efeito neste gif animado:
Esse problema pode ser facilmente corrigido utilizando a propriedade “Anchor” dos controles.
Propriedade Anchor
A propriedade “Anchor“, como o próprio nome diz, implementa um efeito de “âncora” nos controles do Windows Forms. Por padrão, quando adicionamos um controle dentro de um formulário, ele vem com a âncora configurada para “Top, Left” (topo, esquerda). Isso faz com que o controle fique “grudado” no formulário, só que tomando como base o canto superior esquerdo.
Para melhorar o comportamento dos controles do exemplo apresentado anteriormente, podemos alterar a propriedade “Anchor” de alguns controles. Vamos alterar essa propriedade para “Top,Left,Right” nos TextBoxes e Button indicados em vermelho e “Top,Bottom,Left,Right” no DataGridView azul:
Com essas alterações, confira o novo comportamento dos controles:
Como você pode perceber, a propriedade “Anchor” cola a extremidade do controle a uma borda específica do formulário e faz com que ele se redimensione automaticamente quando o formulário muda de tamanho.
Para que você entenda melhor o efeito de cada uma das opções de “Anchor“, vou demonstrar todas as possibilidades com gifs animados abaixo:
Sem Anchor (None):
Top:
Bottom:
Top,Bottom:
Left:
Right:
Left,Right:
Bottom,Left,Right:
Top,Left,Right:
Top,Bottom,Left,Right:
Propriedade Dock
Além da propriedade “Anchor“, temos também à nossa disposição no Windows Forms a propriedade “Dock“. Com ela, podemos “docar” controles em uma extremidade do formulário (ou do contêiner onde o controle está posicionado). Por exemplo, ao configurarmos o “Dock” do DataGridView para “Bottom“, ele se comportaria da seguinte maneira:
Note que, ao configurarmos qualquer tipo de “Dock” o “Anchor” será automaticamente alterado para “Top,Left“. Não é possível utilizarmos o “Anchor” em combinação com o “Dock“. Levando isso em consideração, notamos que o “Dock” é mais utilizado somente quando queremos que um controle ocupe todo o espaço do formulário (ou contêiner pai). Para isso, configuramos a propriedade “Dock” para “Fill“:
TableLayoutPanel
Você já notou que no primeiro exemplo de “Anchor” apresentado neste artigo, o ComboBox e TextBox da primeira linha não ficam com o mesmo tamanho ao aumentarmos o tamanho do formulário? O ComboBox que não está com o “Anchor” fica com um tamanho estático enquanto que o TextBox com “Anchor” tem o seu tamanho aumentado automaticamente. Como poderíamos fazer para que o tamanho do ComboBox e TextBox aumentasse simultaneamente? Para isso, precisamos de um TableLayoutPanel.
Se você está acostumado com o WPF, o TableLayoutPanel nada mais é que o Grid. Com ele, podemos definir linhas e colunas que terão tamanhos fixos, automáticos (que têm o tamanho do controle que está dentro da célula) ou percentuais.
Dessa forma, para que o ComboBox e o TextBox cresçam proporcionalmente, podemos adicionar um TableLayoutPanel com duas linhas e duas colunas. Esse controle se encontra dentro da categoria “Containers” na caixa de ferramentas:
Uma vez adicionado o TableLayoutPanel, arraste os Labels, ComboBox e TextBox para dentro do TableLayoutPanel:
Feito isso, vá para a tela de configuração das linhas e colunas do TableLayoutPanel:
Dentro da tela de configuração, escolha a opção “Rows” e configure ambas as linhas para tamanho “AutoSize“. Com essa configuração, as linhas terão automaticamente o tamanho do controle que está localizado dentro das células:
Agora, você se lembra que acabamos de estudar os efeitos da propriedade “Dock“? Lembra que eu falei sobre a configuração “Fill” do “Dock“? Pois bem, nesse caso, se configurarmos a propriedade “Dock” do ComboBox e TextBox para “Fill“, eles serão automaticamente redimensionados de acordo com o tamanho das colunas do TableLayoutPanel. E se, por fim, configurarmos o “Anchor” do TableLayoutPanel para “Top,Left,Right” teremos o seguinte resultado:
Percebeu que agora o ComboBox e TextBox estão aumentando e diminuindo proporcionalmente, de forma que cada um ocupe 50% da largura do formulário? Bem bacana, não é mesmo?
Ajuste de DPI
Até esse ponto, nós só falamos do ajuste automático dos controles quando alteramos o tamanho do formulário. Porém, como fica a situação em que o usuário tenha aumentado o DPI? Para quem não sabe, DPI é a porcentagem que os controles ocupam de acordo com a resolução da tela. Essa opção pode ser alterada nas configurações de resolução de tela, clicando no botão “Make text and other items larger or smaller“:
Quando a configuração está em 100%, não temos nenhum problema. Porém, quando o usuário altera essa configuração para outro valor, dependendo do manifesto da aplicação, ela pode acabar ficando toda desfigurada.
Por padrão, os projetos Windows Forms não são “DPI aware“. Ou seja, elas não implementam ajuste automático dos controles dependendo do DPI (como o WPF faz automaticamente). Dessa forma, se não alterarmos nenhuma configuração relacionada ao DPI e executarmos a nossa aplicação em um computador que está com um DPI diferente, as janelas serão automaticamente redimensionadas dependendo da configuração.
Porém, um detalhe importante é que o Windows fará esse redimensionamento como se ele estivesse “esticando” um bitmap. Ou seja, conseguiremos reparar uma certa perda de qualidade visual no aplicativo (mais especificamente, a aplicação parecerá um pouco “borrada“).
Uma outra opção que temos para solucionar o problema da alteração do DPI é configurarmos o nosso projeto Windows Forms como “DPI aware“. Podemos fazer isso adicionando um arquivo de manifesto no projeto incluindo a seguinte tag:
<asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> </asmv3:windowsSettings> </asmv3:application>
Com isso, o nosso aplicativo não será mais redimensionado automaticamente, ou seja, ele ficará do mesmo tamanho em que ele foi desenvolvido. Isso pode causar o efeito do aplicativo ficar extremamente pequeno caso a resolução e o DPI estejam muito altos.
Por fim, é possível ainda lidarmos com a alteração de DPI manualmente, redimensionando os controles da maneira que quisermos. Isso pode ser feito através de um override no método “ScaleControl” dos formulários da aplicação. Eu não recomendo essa alternativa, uma vez que ela é muito complicada de ser implementada e difícil de ser mantida. Porém, caso você se interesse sobre esse tema, aqui vão algumas referências:
Per-Monitor DPI Aware in Windows Forms
How to control the font DPI in .NET WinForms app
WinForms Scaling at Large DPI Settings–Is It Even Possible?
Concluindo
Apesar do Windows Forms não implementar o ajuste automático dos controles dependendo da resolução e DPI (como no WPF), é possível fazermos esses tipos de ajustes para deixarmos os nossos formulários mais amigáveis com diferentes resoluções. Não é uma tarefa fácil, mas, também não é uma tarefa impossível.
Neste artigo você conferiu como utilizar as propriedades “Anchor” e “Dock” para ajustarmos os tamanhos dos controles automaticamente dependendo do tamanho do formulário. Além disso, vimos também como aumentar o tamanho de controles proporcionalmente através do TableLayoutPanel. Por fim, vimos uma breve explicação de como o Windows Forms lida com a alteração de DPI.
E você, já teve esse tipo de problema com as suas aplicações Windows Forms? Como é que você acabou resolvendo? Conte para a gente nos comentários se você utilizou “Anchor“, “Dock” ou outro tipo de solução.
Por fim, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário logo abaixo.
Até a próxima!
André Lima
Image by Pixabay used under Creative Commons
https://pixabay.com/en/monitor-monitor-wall-big-screen-1054600/
Trabalhando com o Report Viewer no WPF Como podemos exportar relatórios do Report Viewer?
Fala André, ótimo artigo muitas pessoas não sabem usar direito a propriedade anchor ou mesmo surge uma certa dúvida de como usar e quando usar. Eu mesmo já passei por isso rs.
Obrigado, e continue assim !
Olá Lucas! Valeu pelo comentário!
Realmente vejo muita gente não sabendo utilizar essas propriedades.. Pelo menos agora com os exemplos do artigo qualquer um vai conseguir entender..
Abraço!
André Lima
Parabéns André pelo artigo, como sempre, ajudando e muito… já sofri com esse problema e um detalhe não tinha achado nada até agora que detalha-se dessa maneira sobre o assunto.
Continue assim. Esta ajudando muita gente… eu sou um desses…
Abraço!
Thyago Gonçalves
Olá Thyago, obrigado pelo comentário! Fico feliz que os artigos estejam te ajudando..
Grande abraço!
André Lima
Muito bom seu Post André. Sempre tive dúvidas de como utilizar os Containers e a propriedade Dock no Winos Forms. A propriedade Anchor para mim e nova. Mas pelo que vi se adapta melhor do que o Dock. Muito obrigado pela dica.
Olá Maik, muito obrigado!
Fico feliz que o artigo tenha te ajudado a entender melhor as propriedades Dock e Anchor! Qualquer dúvida na implementação, entre em contato..
Abraço!
André Lima
Super interessante, tem gente que quebra cabeça com isso, valeu André.
Olá Italo, obrigado pelo comentário! Que legal que você gostou do artigo..
Abraço!
André Lima
[…] isso está se tornando um problema muito comum. Existem algumas maneiras de resolver esse problema (eu até já escrevi um artigo sobre isso), mas, não é tão fácil como no […]
muito bom, o melhor guia disponivel pra dimensionamento de objetos, ajudou muito
Olá André, muito obrigado pelo comentário! Fico feliz que esse meu tutorial tenha te ajudado aí no seu projeto.. Qualquer dificuldade, é só entrar em contato..
Abraço!
André Lima
Excelente, parabéns pela dedicação. Me ajudou bastante.
Valeu Marcelo! Que bom que eu consegui te ajudar com o conteúdo desse artigo.. Qualquer dúvida é só entrar em contato..
Abraço!
André Lima
Boa tarde André e parabéns pelo material.
Sou iniciante na plataforma web com asp.net e tenho problema com usuários que utilizam o zoom do browser acima de 100%. Preciso saber se é possível e como fazer para alterar a configuração do zoom do usuário logado via aplicação.
Grato,
Olá Gabriel, obrigado pelo comentário!
Sendo bem sincero com você, eu não tenho praticamente nenhuma experiência com desenvolvimento web, então eu não seria a melhor pessoa para te ajudar nesse caso.. Porém, eu imagino que você consiga encontrar alguma gambiarra em javascript que faça esse tipo de coisa.. Você já chegou a dar uma olhada nesta thread do StackOverflow:
javacript – Changing the browser zoom level
Entretanto, será que não seria mais interessante você construir o seu site de forma que ele seja responsivo e se comporte corretamente em qualquer tamanho de janela e nível de zoom?
Abraço!
André Lima
Show!
Valeu, André!
Abraço!
André Lima
Mais uma vez obrigado pelo seus ensinamentos, são de grande valia para mim.
Valeu, Marcelo! Fico feliz por ter conseguido ajudar.. :)
Abraço!
André Lima
Boa tarde, André.
Muito bom seu artigo! Me ajudou a entender alguns pontos que estava com dificuldade.
Cara, eu to com um problema na minha aplicação, que quando o usuário altera a escala da fonte do windows, altera também da aplicação.
Depois de ler seu artigo, consegui contornar o problema, configurando a propriedade gdiScaling como true. Dessa forma a fonte da aplicação não está mais sendo alterada. Por outro lado, eu utilizo na aplicação alguns componentes UserControl e também componentes WPF (combobox), esses componentes começaram a apresentar problema depois que eu alterei a propriedade mencionada. Os componentes estão saindo do seu local, e ficando em outro ponto do formulário. O tamanho não está sendo respeitado também.
Você tem alguma idéia do que poderia estar acontecendo?
Muito obrigado!
Att.,
Jorge.
Olá Jorge, muito obrigado pelo comentário!
Cara, isso é realmente uma batalha.. Tem que ir ajustando na tentativa e erro.. Quanto mais propriedades você fixa no formulário (como tamanho, margens, etc, sem utilizar Anchor e Dock), mais difícil fica de ajustar.. Principalmente se você estiver utilizando componentes mais complexos (a propósito, por que você está utilizando o ComboBox do WPF no Windows Forms – e como você está fazendo isso?)..
Me manda um screenshot de como está ficando a tela para eu ter uma noção.. Se preferir entrar em contato por e-mail, meu endereço é o contato [arroba] andrealveslima [ponto] com [ponto] br
Abraço!
André Lima
Ótimo conteúdo André. Parabéns!
Se tratando de Windows Forms, qual a resolução padrão(mais utilizada) atualmente?
Olá Fabio, muito obrigado pelo comentário!
Não vou saber te dizer qual é a resolução mais utilizada, porém, aonde eu trabalho nós costumamos nos basear na resolução 1024×768 para desenharmos os formulários.. Tem atentido bem os nossos clientes..
Abraço!
André Lima