69 votes

Convertir une chaîne en couleur en C#

Je rencontre un problème : comment convertir des chaînes d'entrée comme "RED" en type de couleur réelle ? Color.Red en C#. Existe-t-il un bon moyen de le faire ?

Je pourrais penser à utiliser une instruction switch et une instruction cases pour chaque type de couleur, mais je ne pense pas que ce soit assez intelligent.

105voto

James Curran Points 55356
 Color red = Color.FromName("Red");   

Le MSDN ne le précise pas, il y a donc de fortes chances qu'il soit sensible à la casse. (MISE À JOUR : Apparemment, il ne l'est pas).

D'après ce que je sais, ColorTranslator.FromHtml est aussi.

Si Color.FromName ne trouve pas de correspondance, il renvoie new Color(0,0,0);

Si ColorTranslator.FromHtml ne trouve pas de correspondance, il lève une exception.

UPDATE :

Comme vous utilisez Microsoft.Xna.Framework.Graphics.Color, cela devient un peu délicat :

using XColor = Microsoft.Xna.Framework.Graphics.Color;
using CColor = System.Drawing.Color;

 CColor clrColor = CColor.FromName("Red"); 
 XColor xColor = new XColor(clrColor.R, clrColor.G, clrColor.B, clrColor.A);

0 votes

Puisque je développe ceci dans le XNA GameStudio, après avoir entré votre code, le programme se plaint : Erreur 1 'Microsoft.Xna.Framework.Graphics.Color' ne contient pas de définition pour 'FromName' et aucune méthode d'extension 'FromName' acceptant un premier argument de type 'Microsoft.Xna.Framework.Graphics.Color' n'a pu être trouvée (il vous manque une directive using ou une référence d'assemblage). C:\Users\Guoguo\Desktop\MapWorld2\MapWorld\GameObject.cs 194 27 MapWorld Savez-vous quelle est l'erreur ? Merci.

3 votes

+1 pour avoir mentionné le comportement différent lorsqu'une correspondance n'est pas trouvée.

0 votes

Microsoft.Xna.Framework n'est pas le bon espace de nom. Utilisez System.Drawing

22voto

Larsenal Points 17080
System.Drawing.Color myColor = System.Drawing.ColorTranslator.FromHtml("Red");

(Utilisez ma méthode si vous voulez accepter les couleurs hexagonales de style HTML).

15voto

Jon Skeet Points 692016

(Cela aurait été vraiment bien si vous aviez mentionné quelle Color type qui vous intéressait au départ...)

Une façon simple de le faire est de construire un dictionnaire par réflexion :

public static class Colors
{
    private static readonly Dictionary<string, Color> dictionary =
        typeof(Color).GetProperties(BindingFlags.Public | 
                                    BindingFlags.Static)
                     .Where(prop => prop.PropertyType == typeof(Color))
                     .ToDictionary(prop => prop.Name,
                                   prop => (Color) prop.GetValue(null, null)));

    public static Color FromName(string name)
    {
        // Adjust behaviour for lookup failure etc
        return dictionary[name];
    }
}

Cela sera relativement lent pour la première consultation (pendant qu'elle utilise la réflexion pour trouver toutes les propriétés) mais devrait être très rapide par la suite.

Si vous voulez qu'il soit insensible à la casse, vous pouvez passer quelque chose comme StringComparer.OrdinalIgnoreCase comme un argument supplémentaire dans le ToDictionary appel. Vous pouvez facilement ajouter TryParse etc. si vous le souhaitez.

Bien sûr, si vous n'en avez besoin qu'à un seul endroit, ne vous embêtez pas à créer une classe séparée, etc :)

0 votes

Il semble que ce soit la meilleure façon de répondre à l'inverse de cette question : stackoverflow.com/questions/3392030/

8voto

Davy8 Points 12458

Puisque l'OP a mentionné dans un commentaire qu'il utilise Microsoft.Xna.Framework.Graphics.Color plutôt que System.Drawing.Color vous pouvez d'abord créer un System.Drawing.Color puis le convertir en un Microsoft.Xna.Framework.Graphics.Color

public static Color FromName(string colorName)
{
    System.Drawing.Color systemColor = System.Drawing.Color.FromName(colorName);   
    return new Color(systemColor.R, systemColor.G, systemColor.B, systemColor.A); //Here Color is Microsoft.Xna.Framework.Graphics.Color
}

0 votes

La deuxième ligne devrait être : Color xnaColor = new Color(systemColor.R, systemColor.G, systemColor.B, systemColor.A) ; Mais je pense que c'est la façon la plus simple d'accomplir ce que Robert a demandé.

0 votes

...et une bonne return devrait être ajouté aussi :)

3voto

MIke Zirkle Points 21

Cela a bien fonctionné pour mes besoins ;) J'espère que quelqu'un pourra l'utiliser....

    public static Color FromName(String name)
    {
        var color_props= typeof(Colors).GetProperties();
        foreach (var c in color_props)
            if (name.Equals(c.Name, StringComparison.OrdinalIgnoreCase))
                return (Color)c.GetValue(new Color(), null);
        return Colors.Transparent;
    }

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:

X