我正在使用.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; }
}
给我一个编译错误
属性参数必须是属性参数类型的常量表达式、类型表达式或数组创建表达式。
我还尝试使用Byte[]
并用静态颜色类的 A、R、G 和 B 属性填充它,但我得到了同样的错误。即使使用string
并将其设置为Color.Red.Name
也不起作用。
System.Drawing.KnownColor
枚举本来是完美的,它存在于.NET Framework和.NET Core中,但不是.NET Standard,因为Xamarin没有它。(请参阅此 Github 线程(
所以我想知道我在 .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);
当你发现自己在.NET Standard中,System.Drawing.Common Nuget包,你有一个完美的匹配:
var color = ColorTranslator.FromHtml(attribute.BackgroundColor);
如果你想避免魔术字符串,那么你可以创建一个简单的颜色列表:
static class Colors {
public const string Red = "red";
}
此列表甚至可以通过简单的 T4 转换自动生成(参见示例(,列表可以通过以下方式获得:
typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public)
.Select(x => ((Color)x.GetValue(null)).ToString());
注意:不要忘记用[Serializable]
标记您的自定义属性。
您可以通过将BackgroundColor
设置为常量来解决编译器错误。
public class FooModel
{
[Required]
public int Id { get; set; }
[DesignAttribute(Width = 20, BackgroundColor = Constants.RedArgb)]
public string Name { get; set; }
}
public static class Constants
{
public const int RedArgb = -65536;
}
使用类型本身的属性解决
public class MyClass
{
[MyAttribute(BackgroundColorPropertyName = nameof(MyPropertyColor))]
public string MyProperty { get; set; }
public static Color MyPropertyColor {get; set;} = Color.Red;
}
然后用
(Color)from.GetProperty(attribute.BackgroundColorPropertyName,
BindingFlags.Static | BindingFlags.Public)