我正在使用 .NET Standard 2.0,我想创建一个带有颜色属性的自定义属性。
例如:
public class DesignAttribute : Attribute
{
public int Width { get; set; }
public ??? BackgroundColor { get; set; }
}
问题是这个属性应该是常量或原始类型,并在编译时解析。
所以它的类型不能是 System.Drawing.Color
也不能是 ARGB 表示的 int
因为
public class FooModel
{
[Required]
public int Id { get; set; }
[DesignAttribute(Width = 20, BackgroundColor = Color.Red.ToArgb())]
public string Name { get; set; }
}
给我一个编译错误
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
我还尝试使用 Byte[]
并用我的静态颜色类的 A、R、G 和 B 属性填充它,但我得到了同样的错误。即使使用 string
并将其设置为 Color.Red.Name
也不起作用。
System.Drawing.KnownColor
枚举本来是完美的,它存在于 .NET Framework 和 .NET Core 中,但不存在于 .NET Standard 中,因为 Xamarin 没有它。 (参见此 Github thread)
所以我想知道我在 .NET Standard 中有哪些选择?如何将颜色表示为有效的属性参数?
谢谢
最佳答案
您不应使用 GDI+ System.Drawing.Color
或 WPFSystem.Windows.Media.Color
,因为您已经注意到它们不可移植。您可以定义自己的一组常量,但这是一项乏味的工作,就像重新发明轮子一样,幸运的是 WPF 本身(和 HTML...)给了我们一个提示:
public class DesignAttribute : Attribute
{
public int Width { get; set; }
public string BackgroundColor { get; set; }
}
现在你可以:
public class FooModel
{
[Required]
public int Id { get; set; }
[DesignAttribute(Width = 20, BackgroundColor = "red"]
public string Name { get; set; }
}
当然你必须支持多种格式(例如#abcdef
),值可以按原样使用(例如当呈现为 HTML 时)或转换为另一种结构(如果,例如,客户端是 WPF 或其他支持 .NET Standard 的绘图框架。在前一种情况下,它可以(假设您在 WPF 应用程序中以 .NET Framework 为目标)简单如下:
var color = (Color)colorConverter.ConvertFromString(attribute.BackgrouncColor);
作为you found您自己在 .NET Standard System.Drawing.Common Nuget 包你有绝配:
var color = ColorTranslator.FromHtml(attribute.BackgroundColor);
如果你想避免使用魔法字符串,那么你可以创建一个简单的颜色列表:
static class Colors {
public const string Red = "red";
}
这个列表甚至可以用一个简单的 T4 transformation 自动生成(见示例),列表可以通过以下方式获得:
typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public)
.Select(x => ((Color)x.GetValue(null)).ToString());
注意:不要忘记用[Serializable]
标记您的自定义属性。
关于c# - 在 .NET Standard 的属性中表示颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51837351/