Comment puis-je convertir un WPF taille physique de pixels?
Quel est le meilleur moyen de convertir un WPF (indépendant de la résolution) la largeur et la hauteur de la physique pixels de l'écran?
Je vais les montrer WPF contenu dans un WinForms Formulaire (via ElementHost) et en essayant de travailler avec certains de dimensionnement de la logique. Je l'ai bien fonctionner lorsque le système d'exploitation est en cours d'exécution par défaut de 96 dpi. Mais il ne fonctionne pas lorsque le système d'exploitation est fixée à 120 dpi ou une autre résolution, parce qu'alors un WPF élément qui rend compte de sa Largeur 96 sera effectivement 120 pixels de large autant que WinForms est concerné.
Je ne pouvais pas trouver toutes les "pixels par pouce" paramètres de Système.De Windows.SystemParameters. Je suis sûr que je pourrais utiliser les WinForms équivalent (Système d'.De Windows.Les formulaires.SystemInformation), mais est-il une meilleure façon de le faire (lire: un chemin à l'aide de WPF Api, plutôt que d'utiliser des WinForms Api et manuellement de faire le calcul)? Quel est le "meilleur moyen" pour convertir WPF "pixels" de vrais pixels de l'écran?
EDIT: je suis aussi à la recherche de le faire avant le contrôle WPF est indiqué sur l'écran. Il ressemble Visuelle.PointToScreen pourraient être apportées à me donner la bonne réponse, mais je ne peux pas l'utiliser, car le contrôle n'est pas apparenté encore et je reçois InvalidOperationException "Ce Visuel n'est pas connecté à un PresentationSource".
- Est-ce cela que vous cherchez? books.google.com/...
- c'est juste une vue d'ensemble conceptuelle - il ne donne pas de code pour convertir à partir de WPF de pixels, et il n'a pas d'expliquer la façon de traiter les conditions aux limites.
Vous devez vous connecter pour publier un commentaire.
La transformation d'une taille connue à l'appareil pixels
Si votre élément visuel est déjà attaché à un PresentationSource (par exemple, c'est une partie d'une fenêtre qui est visible sur l'écran), la transformation est trouvé cette façon:
Si non, utilisez HwndSource pour créer un temporaire hWnd:
Noter que cette méthode est moins efficace que d'en construire à l'aide d'un hWnd de IntPtr.Zéro, mais je considère qu'il est plus fiable parce que le hWnd créé par HwndSource sera joint à la même dispositif d'affichage comme une réelle nouvellement créé à la Fenêtre. De cette façon, si différents dispositifs d'affichage ont différentes indicateur de performance, vous êtes sûr d'obtenir la bonne valeur des DPI.
Une fois que vous avez la transformation, vous pouvez convertir n'importe quelle taille de WPF taille à une taille de pixel:
La conversion de la taille des pixels pour des entiers
Si vous voulez convertir la taille des pixels pour les entiers, vous pouvez tout simplement faire:
mais une solution plus robuste serait celui utilisé par ElementHost:
L'obtention de la taille désirée de UIElement
Pour obtenir la taille souhaitée d'un UIElement vous devez vous assurer qu'elle est mesurée. Dans certaines circonstances, il sera déjà mesurée, soit parce que:
Si votre élément visuel n'a pas été mesurée encore, vous devriez téléphoner à Mesure sur le contrôle ou l'un de ses ancêtres, comme approprié, en passant dans la taille (ou
new Size(double.PositivieInfinity, double.PositiveInfinity)
si vous voulez la taille au contenu:Une fois que la mesure est effectuée, tout ce qui est nécessaire est d'utiliser la matrice de transformer le DesiredSize:
Mettre tous ensemble
Voici une méthode simple qui montre comment obtenir la taille en pixels d'un élément:
Noter que dans ce code, je l'ai appeler Mesurer uniquement si aucun DesiredSize est présent. Cette fournit une méthode pratique pour tout faire, mais a plusieurs lacunes:
À cause de ces raisons, j'ai tendance à omettre la Mesure appel dans GetElementPixelSize et de laisser le client faire.
double
s pour la Largeur et la Hauteur. Je veux la taille réelle que la ElementHost serait de taille, ce qui signifieint
s, arrondi de la même façon ElementHost n'.new HwndSourceParameters("")
. Si vous supprimez le paramètre, et nenew HwndSourceParameters()
, la fenêtre n'a pas de flash, mais tout écailles encore correctement.HwndSource
(lorsque la source==null) des préformes en mal de conversion. Alors soyez prévenus! Un aussi s'il vous plaît ajouter un commentaire pour le cas où l'élément n'a pas été initialisée ou ont déjà été éliminés.GetElementPixelSize
ne compile pas, comme c'est (évidemment, vous ne pouvez pas réutilisersource
comme ça).transformToDevice = source.TransformToDevice;
à ceci:transformToDevice = source.CompositionTarget.TransformToDevice;
J'ai trouvé un moyen de le faire, mais je ne l'aime pas beaucoup:
Je ne l'aime pas parce que (a) elle nécessite une référence à System.Le dessin, plutôt que d'utiliser les Api WPF; et (b) je dois faire le calcul moi-même, ce qui signifie que je suis la duplication de WPF détails de mise en œuvre. Dans .NET 3.5, j'ai tronquer le résultat du calcul pour correspondre à ce ElementHost avec AutoSize=true, mais je ne sais pas si ce sera toujours précis dans les futures versions de .NET.
Cela ne semble pas fonctionner, donc je vais le poster dans le cas où il aide les autres. Mais si quelqu'un a une meilleure réponse, s'il vous plaît, post loin.
NotifyIcon
s'privé 'de la fenêtre' valeur que le hwnd passé àFromHwnd
. Privé de la valeur est la fragilité des risques pour l'avenir MS changements, mais il a été rapide et semble bien fonctionner. Pour la description de l'obtention de cette valeur, voir CodeProject exemple, mais si non disponible ce AFIN de répondre comprend le code de réflexion pour obtenir leNativeWindow.Handle
.Simple proportion entre De l'écran.WorkingArea et SystemParameters.WorkArea:
Cela fonctionne bien avec plusieurs moniteurs ainsi.
Viens de faire une recherche rapide dans le ObjectBrowser et trouvé quelque chose d'assez intéressant, vous pourriez vouloir vérifier.
Système.De Windows.Forme.AutoScaleMode, il possède une propriété appelée PPP. Voici les docs, il pourrait être ce que vous cherchez :
S'appliquent qu'à votre formulaire, il devrait faire l'affaire.
{profiter}