Todos os ContainerControls devem ser definidos para o mesmo AutoScaleMode = Font
. (A fonte manipulará as alterações de DPI e as alterações na configuração do tamanho da fonte do sistema; o DPI manipulará apenas as alterações de DPI, não as alterações na configuração do tamanho da fonte do sistema.)
Todos os ContainerControls também devem ser definidos com o mesmo AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
, assumindo 96 dpi (veja o próximo marcador) e a fonte padrão do MS Sans Serif (veja o marcador dois abaixo). Isso é adicionado automaticamente pelo designer com base no DPI no qual você abre o designer ... mas estava ausente em muitos dos nossos arquivos de designer mais antigos. Talvez o Visual Studio .NET (a versão anterior ao VS 2005) não estivesse adicionando isso corretamente.
Faça todo o seu trabalho de designer em 96dpi (poderemos mudar para 120dpi; mas a sabedoria na internet diz que adere a 96dpi; a experimentação está em ordem; por design, isso não deve importar, pois apenas altera a AutoScaleDimensions
linha que o designer insere). Para definir o Visual Studio para ser executado em 96dpi virtual em uma tela de alta resolução, localize seu arquivo .exe, clique com o botão direito do mouse para editar as propriedades e, em Compatibilidade, selecione "Substituir o comportamento de dimensionamento de alta DPI. Dimensionamento realizado por: Sistema".
Certifique-se de nunca definir a fonte no nível do contêiner ... apenas nos controles de folha OU no construtor do formulário mais básico, se desejar uma fonte padrão para todo o aplicativo que não seja o MS Sans Serif. (A configuração da fonte em um contêiner parece desativar o dimensionamento automático desse contêiner porque vem em ordem alfabética após as configurações das configurações AutoScaleMode e AutoScaleDimensions.) NOTA: se você alterar a fonte no construtor do formulário mais básico, isso causará suas AutoScaleDimensions para calcular de maneira diferente de 6x13; em particular, se você mudar para a interface do usuário do Segoe (a fonte padrão do Win 10), será 7x15 ... precisará tocar em todos os formulários do Designer para que possa recalcular todas as dimensões desse arquivo .designer, incluindo o AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
.
NÃO use Anchor Right
ou Bottom
ancorado a um UserControl ... seu posicionamento não será dimensionado automaticamente; em vez disso, solte um painel ou outro contêiner no seu UserControl e ancore seus outros controles nesse painel; ter o uso Painel Doca Right
, Bottom
ou Fill
em seu UserControl.
Somente os controles nas listas Controles, quando ResumeLayout
no final da InitializeComponent
chamada, serão dimensionados automaticamente ... se você adicionar controles dinamicamente, precisará SuspendLayout();
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ResumeLayout();
desse controle antes de adicioná-lo. E seu posicionamento também precisará ser ajustado se você não estiver usando os modos Dock ou um Gerenciador de layout como FlowLayoutPanel
ou TableLayoutPanel
.
As classes base derivadas de ContainerControl
devem deixar AutoScaleMode
definido como Inherit
(o valor padrão definido na classe ContainerControl
; mas NÃO o padrão definido pelo designer). Se você configurá-lo para qualquer outra coisa e, em seguida, sua classe derivada tentar defini-la como Font (como deveria), o ato de definir isso para Font
limpar a configuração do designer AutoScaleDimensions
, resultando na desativação do auto-scaling! (Essa diretriz combinada com a anterior significa que você nunca pode instanciar classes base em um designer ... todas as classes precisam ser projetadas como classes base ou como folhas!)
Evite usar Form.MaxSize
estaticamente / no Designer. MinSize
e MaxSize
no formulário não escalam tanto quanto todo o resto. Portanto, se você fizer todo o seu trabalho em 96 dpi, quando estiver em um DPI mais alto MinSize
, não causará problemas, mas poderá não ser tão restritivo quanto o esperado, mas MaxSize
poderá limitar a escala do tamanho, o que pode causar problemas. Se você quiser MinSize == Size == MaxSize
, não faça isso no Designer ... faça isso no seu construtor ou OnLoad
substitua ... defina ambos MinSize
e MaxSize
para o tamanho em escala adequada.
Todos os controles de um determinado Panel
ou Container
devem usar ancoragem ou ancoragem. Se você as misturar, o dimensionamento automático feito por isso Panel
geralmente se comportará mal de maneiras bizarras e sutis.
Ao fazer o auto-dimensionamento, ele tentará dimensionar o formulário geral ... no entanto, se nesse processo for executado no limite superior do tamanho da tela, esse é um limite rígido que poderá estragar (clipe) a escala. Portanto, verifique se todos os formulários no Designer a 100% / 96dpi têm tamanho não superior a 1024x720 (o que corresponde a 150% em uma tela de 1080p ou 300%, que é o valor recomendado pelo Windows em uma tela de 4K). Mas você precisa subtrair a barra de título / legenda gigante do Win10 ... mais parecida com o tamanho máximo de 1000x680 ... que no designer será como 994x642 ClientSize. (Portanto, você pode fazer uma FindAll References no ClientSize para encontrar violadores.)
NumericUpDown
também não dimensionaMargin
adequadamente. Parece que a margem é redimensionada duas vezes. Se eu escalar de volta uma vez, parece bom.AutoScaleMode = Font
não funciona bem para usuários que usam uma fonte muito grande e com Ubuntu. Nós preferimos #AutoScaleMode = DPI
Minha experiência foi bastante diferente da atual resposta votada. Ao percorrer o código da estrutura .NET e ler atentamente o código fonte de referência, concluí que tudo está pronto para o dimensionamento automático funcionar, e havia apenas um problema sutil em algum lugar que atrapalhava. Isso acabou sendo verdade.
Se você criar um layout com refluxo / tamanho automático, quase tudo funcionará exatamente como deveria, automaticamente, com as configurações padrão usadas pelo Visual Studio (a saber, AutoSizeMode = Font no formulário pai e Herdar em todo o resto).
A única opção é se você definiu a propriedade Font no formulário no designer. O código gerado classificará as atribuições em ordem alfabética, o que significa que
AutoScaleDimensions
será atribuído antesFont
. Infelizmente, isso quebra completamente a lógica de dimensionamento automático do WinForms.A correção é simples. Não defina a
Font
propriedade no designer (defina-a no construtor de formulários) ou reordene manualmente essas atribuições (mas você deverá continuar fazendo isso sempre que editar o formulário no designer). Voila, escala quase perfeita e totalmente automática com o mínimo de problemas. Até os tamanhos dos formulários são redimensionados corretamente.Vou listar problemas conhecidos aqui quando os encontrar:
TableLayoutPanel
calcula margens de controle incorretamente . Solução alternativa conhecida: evitar margens e preenchimentos por completo - ou evitar painéis de layout de tabela aninhados.fonte
Font
no designer: Um pensamento vem à mente: vá em frente e defina a fonte no designer, para que você possa projetar com a fonte desejada. ENTÃO no construtor, após o layout, leu a propriedade da fonte e defina o mesmo valor novamente? Ou talvez apenas peça que o layout seja feito novamente? [Advertência: não tive motivos para testar essa abordagem.] Ou, de acordo com a resposta da Knowleech , no designer especifique em pixels (para que o designer do Visual Studio não faça nova escala no monitor de alto DPI), e no código leia esse valor, converta de pixels para pontos (para obter o dimensionamento correto).AutoScaleDimensions
não estava definidonew SizeF(6F, 13F)
como o recomendado na resposta superior. Descobriu-se que, em todas as instâncias, a propriedade Font do formulário havia sido definida (não padrão). Parece que quandoAutoScaleMode = Font
, em seguida,AutoScaleDimensions
é calculada com base na propriedade de fonte do formulário. Além disso, a configuração de dimensionamento no painel de controle do Windows parece afetarAutoScaleDimensions
.Alveje seu aplicativo para .Net Framework 4.7 e execute-o no Windows 10 v1703 (Build Creators Update 15063). Com o .Net 4.7 no Windows 10 (v1703), a MS fez muitas melhorias de DPI .
Para suportá-lo, adicione um manifesto de aplicativo ao seu aplicativo e sinalize que ele oferece suporte ao Windows 10:
Em seguida, adicione
app.config
e declare o aplicativo por monitor consciente. Agora isso é feito no app.config e NÃO no manifesto como antes!Este PerMonitorV2 é novo desde a Atualização do Windows 10 Creators:
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
Agora você pode se inscrever em 3 novos eventos para ser notificado sobre alterações de DPI:
Você também tem três métodos auxiliares sobre manipulação / dimensionamento de DPI:
Control.LogicalToDeviceUnits , que converte um valor de pixels lógicos em pixels do dispositivo.
Control.ScaleBitmapLogicalToDevice , que dimensiona uma imagem de bitmap para o DPI lógico de um dispositivo.
Control.DeviceDpi , que retorna o DPI para o dispositivo atual.
Se você ainda encontrar problemas, poderá desativar as melhorias de DPI através das entradas app.config .
Se você não tiver acesso ao código-fonte, poderá acessar as propriedades do aplicativo no Windows Explorer, acessar a compatibilidade e selecionar
System (Enhanced)
que ativa a escala de GDI para melhorar também o tratamento de DPI:
Execute todas essas etapas e obtenha uma melhor experiência de DPI para aplicativos WinForms. Mas lembre-se de que você precisa direcionar seu aplicativo para .net 4.7 e precisa pelo menos do Windows 10 Build 15063 (Atualização de criadores). Na próxima atualização do Windows 10 1709, poderemos obter mais melhorias.
fonte
Um guia que escrevi no trabalho:
fonte
Achei muito difícil fazer com que o WinForms funcionasse bem com alto DPI. Então, eu escrevi um método VB.NET para substituir o comportamento do formulário:
fonte
Recentemente, deparei-me com esse problema, especialmente em combinação com o redimensionamento do Visual Studio quando o editor é aberto no sistema de alta resolução. Eu achei melhor para manter
AutoScaleMode = Font
, mas para definir as formas de fonte para a fonte padrão, mas especificar o tamanho em pixels , não ponto, ou seja:Font = MS Sans; 11px
. No código, que , em seguida, redefinir a fonte com o padrão:Font = SystemFonts.DefaultFont
e tudo está bem.Apenas meus dois centavos. Eu pensei em compartilhar, porque "manter AutoScaleMode = Font" e "Definir tamanho da fonte em pixel para o Designer" foi algo que não encontrei na internet.
Tenho mais alguns detalhes no meu blog: http://www.sgrottel.de/?p=1581&lang=pt
fonte
Além das âncoras não funcionarem muito bem: eu daria um passo adiante e diria que o posicionamento exato (aka, usando a propriedade Location) não funciona muito bem com o dimensionamento da fonte. Eu tive que resolver esse problema em dois projetos diferentes. Nos dois, tivemos que converter o posicionamento de todos os controles WinForms para usar o TableLayoutPanel e FlowLayoutPanel. O uso da propriedade Dock (geralmente definida como Fill) dentro do TableLayoutPanel funciona muito bem e se adapta bem à DPI do tipo de letra do sistema.
fonte