2010-08-02 23 views
49

Me está encontrando un problema que es cómo convierto cadenas de entrada como "ROJO" al tipo de color real Color.Red en C#. ¿Existe una forma correcta de hacer esto?Convertir cadena a Color en C#

Podría pensar en usar una declaración de cambio y una declaración de casos para cada tipo de color, pero no creo que sea lo suficientemente inteligente.

Respuesta

81
Color red = Color.FromName("Red"); 

El MSDN no dice de una manera u otra, por lo que hay una buena probabilidad de que se trata de casos -sensible. (ACTUALIZACIÓN: Aparentemente, no lo es).

Por lo que puedo decir, ColorTranslator.FromHtml es también.

Si Color.FromName no puede encontrar una coincidencia, devuelve new Color(0,0,0);

Si ColorTranslator.FromHtml no puede encontrar una coincidencia, se emite una excepción.

ACTUALIZACIÓN:

Dado que está utilizando Microsoft.Xna.Framework.Graphics.Color, esto se vuelve un poco complicado:

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

Hola James, gracias por tu comentario. Como estoy desarrollando esto en XNA GameStudio, después de ingresar tu código, el programa se queja: Error 1 'Microsoft.Xna.Framework.Graphics.Color' no contiene una definición para ' FromName 'y ningún método de extensión' FromName 'que acepte un primer argumento de tipo' Microsoft.Xna.Framework.Graphics.Color 'podría encontrarse (¿falta una directiva using o una referencia de ensamblado?) C: \ Users \ Guoguo \ Desktop \ MapWorld2 \ MapWorld \ GameObject.cs 194 27 MapWorld ¿Cuál es el error? Gracias. – Kevin

+3

+1 por mencionar el comportamiento diferente cuando no se encuentra una coincidencia. – Davy8

+0

Microsoft.Xna.Framework no es el espacio de nombres correcto. Use System.Drawing – StingyJack

16
System.Drawing.Color myColor = System.Drawing.ColorTranslator.FromHtml("Red"); 

(Usar mi método si desea aceptar colores hexagonales de estilo HTML.)

-2

que he usado algo como esto antes:

 public static T CreateFromString<T>(string stringToCreateFrom) { 

     T output = Activator.CreateInstance<T>(); 

     if (!output.GetType().IsEnum) 
      throw new IllegalTypeException(); 

     try { 
      output = (T) Enum.Parse(typeof (T), stringToCreateFrom, true); 
     } 
     catch (Exception ex) { 
      string error = "Cannot parse '" + stringToCreateFrom + "' to enum '" + typeof (T).FullName + "'"; 
      _logger.Error(error, ex); 
      throw new IllegalArgumentException(error, ex); 
     } 

     return output; 
    } 
+0

No es una enumeración. –

+0

@Jon Me confundí con ConsoleColor. La misma lógica aún podría aplicarse, ¿verdad? En lugar de Enum.Parse(), puede hacer una comparación insensible a mayúsculas y minúsculas en los nombres de propiedad y devolver el resultado. (obviamente quitando el cheque IsEnum). – Skyler

+0

Creo que encontrar la propiedad por reflexión cada vez sería relativamente doloroso. Mejor, IMO, para construir un diccionario una vez (según mi respuesta). –

14

(Realmente hubiera sido bueno si hubieras mencionado qué tipo de Color estás interesado para empezar ...)

Una forma sencilla de hacer esto es construir justo arriba de un diccionario a través de la reflexión:

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]; 
    } 
} 

Eso será relativamente lento para la primera consulta (si bien utiliza la reflexión para encontrar todas las propiedades) pero debe ser muy rápida después de esto.

Si desea que no distinga entre mayúsculas y minúsculas, puede pasar algo como StringComparer.OrdinalIgnoreCase como argumento adicional en la llamada ToDictionary. Puede agregar fácilmente TryParse métodos etc. si lo desea.

Por supuesto, si sólo necesita esto en un solo lugar, no se moleste con una clase separada etc :)

+0

Parece que esta es la mejor manera de responder el reverso de esta pregunta: http://stackoverflow.com/questions/3392030/convert-a-xna-color-object-to-a-string –

7

Desde el PO mencionado en un comentario que él está usando en lugar de Microsoft.Xna.Framework.Graphics.ColorSystem.Drawing.Color puede crear primero una System.Drawing.Color después convertirlo a 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

La segunda línea debería ser: Color xnaColor = new Color (systemColor.R, systemColor.G, systemColor.B, systemColor.A); Pero creo que esta es la forma más sencilla de lograr lo que Robert pidió. – Romias

+0

@Romias gracias, arreglado. – Davy8

+0

... y se debe agregar una declaración 'return' apropiada :) –

3

Esto funcionó muy bien para mis necesidades;) Espero que alguien pueda usarlo ....

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; 
    } 
3

Para la transferencia de colores a través de XML-secuencias que he encontrado:

Color x = Color.Red; // for example 
String s = x.ToArgb().ToString() 
... to/from xml ... 
Int32 argb = Convert.ToInt32(s); 
Color red = Color.FromArgb(argb); 
2

La forma más sencilla:

string input = null; 
Color color = Color.White; 

TextBoxText_Changed(object sender, EventsArgs e) 
{ 
    input = TextBox.Text; 
} 

Button_Click(object sender, EventsArgs e) 
{ 
    color = Color.FromName(input) 
} 
5

Depende de lo que estés buscando, si necesita System.Windows.Media.Color (como en WPF) es muy fácil:

System.Windows.Media.Color color = (Color)System.Windows.Media.ColorConverter.ConvertFromString("Red");//or hexadecimal color, e.g. #131A84