Option Infer On
Imports System.Text.RegularExpressions
' ...
''' <summary>
''' Convert a string of the format "color [nameOfColor]" or
''' "color [A=a, R=r, G=g, B=b]" to a System.Drawing.Color.
''' </summary>
''' <param name="s">A String representing the colour.</param>
''' <returns>A System.Drawing.Color.</returns>
''' <remarks>Returns fallbackColour if the colour could not be parsed.</remarks>
Public Shared Function ColourFromData(s As String) As Color
Dim fallbackColour = Color.Black
If Not s.StartsWith("color", StringComparison.OrdinalIgnoreCase) Then
Return fallbackColour
End If
' Extract whatever is between the brackets.
Dim re = New Regex("\[(.+?)]")
Dim colorNameMatch = re.Match(s)
If Not colorNameMatch.Success Then
Return fallbackColour
End If
Dim colourName = colorNameMatch.Groups(1).Value
' Get the names of the known colours.
'TODO: If this function is called frequently, consider creating allColours as a variable with a larger scope.
Dim allColours = [Enum].GetNames(GetType(System.Drawing.KnownColor))
' Attempt a case-insensitive match to the known colours.
Dim nameOfColour = allColours.FirstOrDefault(Function(c) String.Compare(c, colourName, StringComparison.OrdinalIgnoreCase) = 0)
If Not String.IsNullOrEmpty(nameOfColour) Then
Return Color.FromName(nameOfColour)
End If
' Was not a named colour. Parse for ARGB values.
re = New Regex("A=(\d+).*?R=(\d+).*?G=(\d+).*?B=(\d+)", RegexOptions.IgnoreCase)
Dim componentMatches = re.Match(colourName)
If componentMatches.Success Then
Dim a = Integer.Parse(componentMatches.Groups(1).Value)
Dim r = Integer.Parse(componentMatches.Groups(2).Value)
Dim g = Integer.Parse(componentMatches.Groups(3).Value)
Dim b = Integer.Parse(componentMatches.Groups(4).Value)
Dim maxValue = 255
If a > maxValue OrElse r > maxValue OrElse g > maxValue OrElse b > maxValue Then
Return fallbackColour
End If
Return System.Drawing.Color.FromArgb(a, r, g, b)
End If
Return fallbackColour
End Function
Function ConvertMyThing(Of T)(text as String) As T
return CType(TypeDescriptor.GetConverter(GetType(T)) _
.ConvertFromInvariantString(text), T)
End Function
8条答案
按热度按时间g6baxovj1#
你熟悉
Color.FromName
吗?应该可以了。http://msdn.microsoft.com/en-us/library/system.drawing.color.fromname(v=vs.110).aspx
Dim slateBlue As Color = Color.FromName("SlateBlue")
@dotNet的答案中有一个例子,说明如何解析出名称。如果你可以选择将颜色值存储为红色、绿色、蓝色和alpha值,那么还有
Color.FromArgb
。http://msdn.microsoft.com/en-us/library/at1k42eh(v=vs.110).aspx
Dim red As Color = Color.FromArgb(alpha, 255, 0, 0)
olqngx592#
只是为了将来的“搜索者”有一个color.toargb和color.fromargb,它们可以转换成一个可串行化的整数,也可以转换成一个可串行化的整数。
jqjz2hbq3#
如果你保存的颜色不是命名的颜色之一,它会以
Color [A=99, R=99, G=19, B=255]
的格式写入。你也可以解析你的字符串:如果愿意,您可以引发FormatException,而不是返回回退值。
z18hc3ub4#
5anewei65#
特别是在序列化时,通常值得使过程不可知-它不应该关心它是ARGB字符串还是命名的颜色。就此而言,它可以不关心它是字体、点、大小、颜色还是矩形。只需使用内置于. NET中的Converter过程。(注意:您的颜色名称看起来不规则,这取决于NET对To和From的处理):
这将给予你一个字符串,它可以转换回字体,点,矩形等,这取决于
v
是什么类型。如果你使用泛型将它 Package 在一个函数中,它也可以不可知地解包:
用法:
ConvertToInvariantString
与ToString
不相同。ToString
生成调试/人类友好文本,如Color [A=99, R=99, G=19, B=255]
或类似的点、大小等。ConvertToInvariantString
的颜色输出将简单地为99, 19, 255
(如果A
为255,则显然省略了A
)。对于颜色,它是伟大的,因为没有解析需要,没有RegEx,没有分裂,加入,没有大惊小怪,没有混乱。作为一个奖金,它将处理点,字体,矩形,大小,十进制...系统。枚举是更多的麻烦比字体。
pgccezyw6#
如果这是winforms为什么不使用我的设置(在解决方案资源管理器中单击我的项目,单击设置选项卡,创建一个新的设置类型system.drawing.color,范围设置为user)。您可以指定一个或多个窗体的背景颜色以使用相关设置(在表单的属性中打开应用程序设置,单击属性绑定,然后在弹出的对话框中将BackColour分配给您创建的设置)。
确保在应用程序关闭时保存设置(My.Settings.save)。最终用户选择的任何颜色都将在会话之间保存。
ffx8fchx7#
这也许是一个老问题,但是,一个答案总是有用的:提取颜色时,将其提取为RGB(这样更容易将其转换回来)。例如,您可以用途:Dim S AS字符串=控制.背景颜色.目标颜色.目标字符串
要恢复该文件,应用途:ctrl.BackColor = Color.FromArgb(CInt(S))在本例中,您不必只是序列化它:该属性可以被提取到一个文本、一个memoryFile、用于XML或任何其他情况下(当你需要把这个设置放在一个“delimeterd”行中,并在以后解析它以恢复这个颜色时)然而,这个BackColor像你的问题中描述的那样更像一个设置,所以,考虑使用My.Settings并在关闭之前保存它,就像Dom Sinclair的回答中描述的那样(见上文),这可能是更好的方法,
szqfcxe28#
如果您将字符串“AAA”放入标签中,您将看到该标签为红色。
例如: