2009-03-02 10 views
3

J'essaie de créer des colonnes de texte pour une application C# qui sera exécutée sur MSN Messenger. Je vais avoir tout à faire pour aligner.Création de colonnes de texte avec une police de largeur variable

Voici un exemple de la sortie que je veux:

1) Pizza Hut           123 Fake St. 
2) Domino's Pizza          123 Fake St. 
3) The Cheesecake Cafe         123 Fake St. 
4) Capital Pizza & Steakhouse       123 Fake St. 
5) Funky Pickle Pizza         123 Fake St. 
6) Boston Pizza           123 Fake St. 
7) Rose Bowl Rouge Lounge        123 Fake St. 
8) Royal Pizza           123 Fake St. 
9) A Columbus Pizza & Donair Inc      123 Fake St. 

Mais parce qu'il est une police à largeur variable, il affiche comme ceci:

1) Pizza Hut          123 Fake St. 
2) Domino's Pizza         123 Fake St. 
3) The Cheesecake Cafe         123 Fake St. 
4) Capital Pizza & Steakhouse        123 Fake St. 
5) Funky Pickle Pizza         123 Fake St. 
6) Boston Pizza          123 Fake St. 
7) Rose Bowl Rouge Lounge        123 Fake St. 
8) Royal Pizza           123 Fake St. 
9) A Columbus Pizza & Donair Inc     123 Fake St. 

J'ai essayé d'utiliser la chaîne C#. PadRight() fonctionne ainsi que la création de ma propre fonction qui ajoute un remplissage en utilisant des espaces et des tabulations. Les deux fonctionnent bien avec les polices de largeur fixe, mais rompent avec les polices de largeur variable.

Y at-il un moyen de déterminer la largeur d'une chaîne dans une police donnée?

Ou avez-vous d'autres suggestions?

Répondre

5

Il suffit d'utiliser la classe TextRenderer. Le cas le plus simple:

Size size = TextRenderer.MeasureText("Hello world", someFont); 

Si vous n'avez pas accès à System.Windows.Fonts Graphics.MeasureString reste, il a certaines limites, mais devrait faire le travail:

Bitmap bmp = new Bitmap(1,1); 
Graphics graphics = Graphics.FromImage(bmp); 
SizeF size = graphics.MeasureString("Hello world", someFont); 

Mais sachez que si le police de votre texte et les espaces doivent être les mêmes, il y aura des cas où vous ne pouvez pas aligner le texte parfaitement. Je ne sais pas ce que MSN Messenger est capable de faire dans votre cas, mais si vous avez accès à au moins un sous-ensemble de HTML, vous n'aurez pas une sortie parfaite. Vous devez également être conscient que si vous effectuez des mesures sur un ordinateur local et que vous envoyez à un autre sans la police correcte installée, vos colonnes ne ressembleront plus à des colonnes. Vous êtes donc limité au sous-ensemble de polices présent sur tous les ordinateurs. .

Si la prise en charge de plusieurs systèmes d'exploitation est également requise, vous aurez de gros problèmes car la police Arial sur Mac et PC ne ressemble pas (et ne mesure pas) exactement la même chose.

+0

On dirait que ça fait partie de l'espace de noms System.Windows.Forms mais mon application est en fait un service Web qui renvoie un service Windows qui se connecte à MSN. Ainsi, l'espace de noms System.Windows est introuvable lorsque j'essaie de créer mon application. Une idée de comment je peux accéder à cette fonction? –

+0

J'ai ajouté un sample avec MeasureString, c'est un peu un truc car vous avez besoin d'un bitmap pour travailler mais il devrait le faire. –

+0

Réponse parfaite! Merci! –

0

Vous pouvez essayer d'utiliser la classe Graphics pour mesurer la longueur de la chaîne pour une police spécifique, puis l'utiliser pour déterminer le nombre d'onglets à utiliser.

+0

Ce serait une bonne solution, mais comment puis-je accéder à une instance de la classe graphique à partir d'un service Web? J'ai trouvé ce code en l'expliquant pour une application Windows Forms: http://www.dev102.com/2008/10/09/measure-string-size-in-pixels-c/ –

-1

Vous devez formater probablement tout en HTML, alors vous pouvez les éléments de sortie de table et TR/TD pour les colonnes

0

Il semble que vous essayez de rendre tout ceci en ASCII dans un seul champ de texte. Oui? Si c'est le cas, c'est assez difficile. Il semble que vous ayez un nombre fixe d'onglets après chacun d'eux en ce moment, et ce serait le problème. Vous pourriez plutôt faire des espaces - que je soupçonne que vous faites avec du padright (pas très familier avec cette fonction spécifique). L'élément clé, cependant, est qu'avec un ASCII pur comme celui-ci, affiché dans une police de largeur variable, vous ne l'obtiendrez jamais parfaitement dans une deuxième colonne. Vous pouvez l'approcher si vous êtes diligent, mais c'est tout - si vous avez une rangée avec beaucoup de capital W, et une autre avec beaucoup de minuscules, vous aurez de grandes différences de largeur, peu importe ce que vous faites. Si vous effectuez un rendu dans GDI, la meilleure approche consiste à appeler DrawText par colonne. Vous pouvez faire une grande chaîne de chaque colonne si vous voulez, et appelez MeasureString sur la première colonne pour déterminer combien d'espace vous devez déplacer pour la deuxième colonne.Ou si c'est une interface où vous pouvez faire du HTML, les tables ou les divs fonctionneraient très bien. Cela dépend des spécificités de votre environnement. Vous pourriez aussi faire quelque chose comme avoir deux étiquettes auto-height-set dans un panneau FlowLayout s'il s'agissait de WinForms, etc. Il y a beaucoup d'options pour faire ce travail, mais pas juste ascii avec une police de largeur variable.

EDIT: En outre, je vous ai vu demander comment obtenir une instance de classe Graphics dans un service Web. Vous pouvez faire quelque chose comme ceci:

private static Bitmap bitmap = new Bitmap(1, 1); 
    private static Graphics graphics = null; 

    public static Graphics GetGeneralGraphics() 
    { 
     if (graphics == null) 
      graphics = Graphics.FromImage(bitmap); 
     return graphics; 
    } 

Vous voulez probablement faire ces variables locales dans un contexte de services Web (que vous disposez correctement lorsque vous avez terminé).