Hallo zusammen,
ich übergebe eine Farbe als string an meine App.
Dort wird aus dem Enum System.Drawing.Color
die passende Farbe herausgesucht und gesetzt.
Das funktioniert, sofern die App als Debug bereitgestellt wird.
Wird sie als Release kompiliert, erhalte ich folgende Meldung:
Fehlermeldung:
Type provided must be an Enum. Parameter name: enumType
Der entsprechende Code:
(Es handelt sich dabei noch um ein Relikt, welches Win CE kompatibel ist. Es gibt sicherlich mittlerweile elegantere Umsetzungen)
public static class Colors
{
public static readonly Dictionary<Color, string> ColorNames = new Dictionary<Color, string>();
public static readonly Dictionary<string, Color> ColorValues = new Dictionary<string, Color>();
static Colors()
{
var fi = typeof(Color).GetFields(BindingFlags.Static | BindingFlags.Public);
for (var iEnum = 0; iEnum < fi.Length; iEnum++)
{
AddColor(fi[iEnum].Name, (Color)fi[iEnum].GetValue(null));
}
var pi = typeof(Color).GetProperties(BindingFlags.Static | BindingFlags.Public);
for (var iEnum = 0; iEnum < pi.Length; iEnum++)
{
if (pi[iEnum].PropertyType == typeof(Color))
{
AddColor(pi[iEnum].Name, (Color)pi[iEnum].GetValue(null, null));
}
}
pi = typeof(SystemColors).GetProperties(BindingFlags.Static | BindingFlags.Public);
for (var iEnum = 0; iEnum < pi.Length; iEnum++)
{
if (pi[iEnum].PropertyType == typeof(Color))
{
AddColor(pi[iEnum].Name,(Color)pi[iEnum].GetValue(null, null));
}
}
}
private static void AddColor(string name, Color color)
{
if (ColorNames.ContainsKey(color))
return;
//Not supported:
if (color == Color.Transparent)
return;
ColorNames.Add(color, name);
ColorValues.Add(name, color);
}
public static string ColorToString(Color color)
{
string name;
if (!ColorNames.TryGetValue(color, out name))
{
name = "Empty";
}
return name;
}
public static Color StringToColor(string colorName)
{
Color color;
if (ColorValues.TryGetValue(colorName, out color))
return color;
if (ColorValues.TryGetValue(string.Format("Color [{0}]", colorName), out color))
return color;
try
{
color = (Color)Enum.Parse(typeof(Color), colorName, true);
}
catch (Exception ex)
{
MessageMgt.CaptureError(ex.Message, "Color " + colorName);
color = Color.Empty;
}
return color;
}
}
Der Fehler tritt bei
Enum.Parse(typeof(Color), colorName, true);
auf. Z.B. wenn man "Green" oder "AliceBlue" übergibt.
Der Debugger hilft mir dabei leider nicht weiter, da der Fehler schließlich nur auftritt, wenn ich ohne Debug-Informationen kompiliere.
Hätte jemand eine Idee woran das liegen könnte?
Oder wie ich es selbst herausfinden kann?
@pinki
Korrekt, die Farben dort sind nur static Color Instanzen mit den festen Farbwerten.
Ergo ist die forcierte Umwandlung zu Enum falsch und knallt immer.
Nachtrag:
Einen Teil des Code kannst du auch durch die static Methoden von Color umsetzen.
Z.B. kannst du StringToColor mit Color.FromName umsetzen, wenn du die Standard Farben verwendest.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Das Problem liegt offenbar nicht an der Umwandlung des Enums.
Wie T-Virus schon schreibt, würde das nie funktionieren!
++
Im Umkehrschluss bedeutet das aber:++
Im Debug-Modus füllt der Konstruktor die Dictionary´s mit Werten. Deshalb läuft der Code gar nicht erst an diese Stelle.
In Release nicht, weshalb der cast fehlschlägt!
Die Frage wäre jetzt nach wie vor: Warum?
Anstelle des Cast auf Color
habe ich nun
Color.FromName(colorName)
verwendet.
Funktioniert sofort und kann nach wie vor einfach mit einer Kompileranweisung (#if WindowsCE) für Windows CE kompilliert werden.
Das Problem ist also gelöst, danke an Euch beide! Interessieren würde mich die Unterscheidung aber trotzdem 😃
[EDIT]
Kopiert man den Code aus dem Xamarin-Projekt in eine Konsolenanwendung funktioniert er sowohl als Debug, als auch per Release.
Hängt also definitiv mit Xamarin zusammen, wo ich den Beitrag ursprünglich eingestellt habe.