En supposant que vous n'essayez pas de l'honneur de l'utilisateur de l'INTERFACE utilisateur le choix de la police (SystemFonts.IconTitleFont), et du code en dur vos formes pour une taille de caractères (par exemple, Tahoma 8pt, Microsoft Sans Serif 8.25 pt), vous pouvez définir votre formulaire AutoScaleMode
de ScaleMode.Dpi
.
Cela va à l'échelle de la taille de la forme et de la plupart des enfants contrôles par le facteur CurrentDpiSetting / 96
en appelant Form.Scale()
, qui s'appelle la protégée ScaleControl()
méthode recursivly sur lui-même et tous les contrôles enfants. ScaleControl
va augmenter d'un contrôle de la position, la taille, la police, etc comme nécessaire pour le nouveau facteur d'échelle.
Attention: Pas tous les contrôles correctement échelle d'eux-mêmes. Les colonnes d'un
listview, par exemple, ne sera pas
plus large que la police devient plus grand. Dans
pour gérer tout cela, vous aurez à
effectuer manuellement supplémentaires de mise à l'échelle comme
nécessaire. - je le faire en remplaçant la
protégés ScaleControl()
méthode, et
mise à l'échelle de la liste des colonnes manuellement:
public class MyForm : Form
{
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
Toolkit.ScaleListViewColumns(listView1, factor);
}
}
public class Toolkit
{
/// <summary>
/// Scale the columns of a listview by the Width scale factor specified in factor
/// </summary>
/// <param name="listview"></param>
/// <param name="factor"></param>
/// <example>/*
/// protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
/// {
/// base.ScaleControl(factor, specified);
///
/// //ListView columns are not automatically scaled with the ListView, so we
/// //must do it manually
/// Toolkit.ScaleListViewColumns(lvPermissions, factor);
/// }
///</example>
public static void ScaleListViewColumns(ListView listview, SizeF factor)
{
foreach (ColumnHeader column in listview.Columns)
{
column.Width = (int)Math.Round(column.Width * factor.Width);
}
}
}
C'est très bien si vous êtes juste en utilisant des contrôles. Mais si jamais vous utilisez tout codé en dur tailles de pixel, vous aurez besoin à l'échelle de votre pixels de largeurs et de longueurs par le facteur d'échelle de la forme. Quelques exemples de situations qui pourraient avoir codé en dur, taille de pixel:
- dessin d'un 25px haute rectangle
- dessin d'une image à l'emplacement (11,56) sur le formulaire
- étirer le dessin d'une icône pour 48x48
- le dessin du texte à l'aide de Microsoft Sans Serif 8.25 pt
- l'obtention de la 32x32 format de l'icône et la farce dans un PictureBox
Si c'est le cas, vous aurez besoin à l'échelle de ces valeurs codées en dur par le "courant facteur d'échelle". Malheureusement, le "courant" facteur d'échelle n'est pas fourni, nous avons besoin de l'enregistrer nous-mêmes. La solution est de supposer qu'initialement, le facteur d'échelle est de 1,0 et à chaque fois, ScaleControl()
est appelé, de modifier le fonctionnement facteur d'échelle par le nouveau facteur.
public class MyForm : Form
{
private SizeF currentScaleFactor = new SizeF(1f, 1f);
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
//Record the running scale factor used
this.currentScaleFactor = new SizeF(
this.currentScaleFactor.Width * factor.Width,
this.currentScaleFactor.Height * factor.Height);
Toolkit.ScaleListViewColumns(listView1, factor);
}
}
Initialement, le facteur d'échelle est - 1.0
. Si le formulaire est ensuite mis à l'échelle en 1.25
, le facteur d'échelle devient alors:
1.00 * 1.25 = 1.25 //scaling current factor by 125%
Si le formulaire est ensuite mis à l'échelle en 0.95
, le nouveau facteur d'échelle devient
1.25 * 0.95 = 1.1875 //scaling current factor by 95%
La raison pour laquelle un SizeF
est utilisé (plutôt qu'une seule valeur à virgule flottante), c'est que mise à l'échelle, les montants peuvent être différents dans les directions x et y. Si un formulaire est mis à l' ScaleMode.Font
, la forme est adaptée à la nouvelle taille de la police. Les polices peuvent avoir différents rapports d'aspect (par exemple, Segoe UI est plus haute police Tahoma). Cela signifie que vous avez à l'échelle des valeurs x et y indépendamment.
Donc si vous voulez placer un contrôle à l'emplacement de (11,56)
, vous aurez à changer votre positionnement du code à partir de:
Point pt = new Point(11, 56);
control1.Location = pt;
pour
Point pt = new Point(
(int)Math.Round(11.0*this.scaleFactor.Width),
(int)Math.Round(56.0*this.scaleFactor.Height));
control1.Location = pt;
La même chose s'applique si vous alliez choisir une taille de police:
Font f = new Font("Segoe UI", 8, GraphicsUnit.Point);
aurait pour devenir:
Font f = new Font("Segoe UI", 8.0*this.scaleFactor.Width, GraphicsUnit.Point);
Et l'extraction d'une 32x32 icône d'une image bitmap allait changer à partir de:
Image i = new Icon(someIcon, new Size(32, 32)).ToBitmap();
pour
Image i = new Icon(someIcon, new Size(
(int)Math.Round(32.0*this.scaleFactor.Width),
(int)Math.Round(32.0*this.scaleFactor.Height))).ToBitmap();
etc.
Soutenir non-standard DPI affiche est un impôt que tous les développeurs devraient payer. Mais le fait que personne ne veut est pourquoi Microsoft a abandonné et est ajouté à Vista, la capacité de la carte graphique pour étirer toutes les applications qui ne disent-ils correctement la poignée de haute résolution.