48 votes

Comment écrire du code WinForms qui s'adapte automatiquement aux paramètres de police et de dpi du système?

Intro: Il y a beaucoup de commentaires qui disent "WinForms n'est pas auto-échelle pour les DPI/paramètres de police; passer à WPF." Cependant, je pense que c'est basé sur .NET 1.1; il semble qu'ils ont fait un très bon travail de mise en œuvre de l'auto-scaling .NET 2.0. Au moins basées sur nos recherches et de tests jusqu'à présent. Cependant, si certains d'entre vous connaissent mieux, nous aimerions entendre parler de vous. (S'il vous plaît ne vous embêtez pas à argumenter, nous devrions passer à WPF... ce n'est pas une option à l'heure actuelle.)

Questions:

  • Ce qui en WinForms n'est PAS auto-échelle correctement et par conséquent devrait être évitée?

  • Ce que les lignes directrices de conception devrait programmeurs suivre lors de la rédaction de WinForms code tel qu'il s'auto-échelle?

Les lignes Directrices de conception que nous avons identifiés à ce jour:

  • Tous les ContainerControls doivent être réglés sur le même AutoScaleMode = Font. (Police va gérer à la fois des DPI et de modifications pour le système de la police réglage de la taille; DPI ne traitera que les DPI des changements, pas de changements à la système de paramètre de taille de police.)

  • Tous les ContainerControls doit également être défini avec AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);, en supposant 96 ppp (voir la balle suivante). Et qui est auto-ajouté par le designer basé sur le DPI vous ouvrez le concepteur... mais manquait de beaucoup de nos plus ancien concepteur de fichiers. Peut-Être Que Visual Studio .NET (la version avant de VS 2005) n'a pas été en ajoutant que dans les correctement.

  • Faire tout votre travail designer en 96 ppp (nous pourrions être en mesure de passer à 120 ppp; mais la sagesse sur l'internet dit de coller à 96 ppp; l'expérimentation est en ordre; de par sa conception, il ne devrait pas question qu'elle change juste l' AutoScaleDimensions ligne que le concepteur inserts).

  • Assurez-vous de ne jamais mettre la Police au niveau du conteneur... seulement sur le feuille de contrôle. (Réglage de la Police sur un Conteneur semble s'éteindre la fonction d'auto-mise à l'échelle de ce conteneur.)

  • Ne PAS utiliser d'Ancrage Right ou Bottom ancré à un UserControl... positionnement automatique de l'échelle; au lieu de cela, la chute d'un Panneau ou d'autres récipient dans votre UserControl et d'Ancrer vos autres Contrôles ce Panneau; utilisation du Panneau de contrôle Quai Right ou Dock Bottom dans votre UserControl.

  • Seuls les contrôles dans les listes de Contrôles lors de l' ResumeLayout à la fin d' InitializeComponent est appelé sera automatiquement mis à l'échelle... si vous ajouter dynamiquement des contrôles, alors vous avez besoin d' SuspendLayout(); AutoScaleDimensions = new SizeF(6F, 13F); AutoScaleMode = AutoScaleMode.Font; ResumeLayout(); sur cette commande avant de l'ajouter dans. Et votre positionnement aurez aussi besoin d'être ajustée, si vous n'êtes pas à l'aide de Quai modes ou un Gestionnaire de Mise en page comme FlowLayoutPanel ou TableLayoutPanel.

  • Base de classes dérivées ContainerControl devrait quitter AutoScaleMode ensemble de Inherit (la valeur par défaut définie dans la classe ContainerControl; mais PAS la valeur par défaut définie par le concepteur). Si vous le réglez à autre chose, et puis votre classe dérivée essaie de le mettre à la Police (comme il se doit), puis la loi du paramètre d' Font va effacer le concepteur du réglage de l' AutoScaleDimensions, résultant de la désactivation de l'auto-scaling! (Cette directive est combiné avec l'avant un signifie que vous ne pouvez jamais instancier des classes de base dans un concepteur... toutes les classes doivent être conçus comme des classes de base ou en tant que feuille de classes!)

  • Évitez d'utiliser des Form.MaxSize statiquement / dans le Concepteur. MinSize et MaxSize sur le Formulaire ne s'adaptent pas aussi bien que tout le reste. Donc, si vous faites tout votre travail à 96 ppp, alors quand en plus le DPI votre MinSize ne cause pas de problèmes, mais peut-être pas aussi restrictive que tu attendais, mais votre MaxSize peut limiter votre Taille de la mise à l'échelle, ce qui peut causer des problèmes. Si vous souhaitez MinSize == Size == MaxSize, ne pas le faire dans le Concepteur de... le faire dans le constructeur ou l' OnLoad remplacer... définir à la fois MinSize et MaxSize de votre correctement sur l'échelle de Taille.

  • Tous les Contrôles sur un particulier Panel ou Container utilisez l'Ancrage ou d'Amarrage. Si vous les mélangez, l'auto-scaling fait par l' Panel souvent en mal de subtile façon bizarre.

Sont un de ces incorrecte ou inadéquate? Autres lignes directrices que nous devrions adopter? Existe-il d'autres modèles qui doivent être évités? Toutes les autres lignes directrices sur ce serait très apprécié.

4voto

Jason Williams Points 31

J'ai trouvé très difficile de faire en sorte que WinForm joue bien avec une résolution élevée. J'ai donc écrit une méthode VB.NET pour redéfinir le comportement du formulaire:

 Public Shared Sub ScaleForm(WindowsForm As System.Windows.Forms.Form)
    Using g As System.Drawing.Graphics = WindowsForm.CreateGraphics
        Dim sngScaleFactor As Single = 1
        Dim sngFontFactor As Single = 1
        If g.DpiX > 96 Then
            sngScaleFactor = g.DpiX / 96
            'sngFontFactor = 96 / g.DpiY
        End If
        If WindowsForm.AutoScaleDimensions = WindowsForm.CurrentAutoScaleDimensions Then
            'ucWindowsFormHost.ScaleControl(WindowsForm, sngFontFactor)
            WindowsForm.Scale(sngScaleFactor)
        End If
    End Using
End Sub
 

3voto

Brannon Points 1299

Outre les ancres ne fonctionne pas très bien: je voudrais aller un peu plus loin et dire que le positionnement exact (aka, en utilisant l'Emplacement de la propriété) ne fonctionne pas très bien avec l'échelle de police. J'ai eu à traiter de cette question dans deux projets différents. Dans deux d'entre eux, nous avons dû convertir le positionnement de tous les WinForms des contrôles à l'aide de la TableLayoutPanel et FlowLayoutPanel. À l'aide de la station d'accueil (généralement fixé à Remplir) des biens à l'intérieur de la TableLayoutPanel fonctionne très bien et à des échelles très bien avec le système de la police DPI.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: