在.NET中将字符串转换为System.Color

在.NET中将字符串转换为System.Color,.net,vb.net,.net,Vb.net,您好,我正在尝试在VB.NET上制作这个应用程序,用户可以在其中更改应用程序的背景颜色,当应用程序关闭时,颜色应该保存为XML。节省是小菜一碟,但现在真正的难题是如何将字符串“Color[white]”转换为System.Color 我已经用谷歌搜索了我的问题,但没有结果。另外,我对Color.FromName已经很熟悉了 非常感谢高级版。您熟悉颜色。FromName?应该这样做 Dim slateBlue As Color=Color.FromName(“slateBlue”) @dotNe

您好,我正在尝试在VB.NET上制作这个应用程序,用户可以在其中更改应用程序的背景颜色,当应用程序关闭时,颜色应该保存为XML。节省是小菜一碟,但现在真正的难题是如何将字符串
“Color[white]”
转换为
System.Color

我已经用谷歌搜索了我的问题,但没有结果。另外,我对
Color.FromName
已经很熟悉了


非常感谢高级版。

您熟悉
颜色。FromName
?应该这样做

Dim slateBlue As Color=Color.FromName(“slateBlue”)

@dotNet的答案中有一个例子,说明如何解析出名称。如果可以选择将颜色值存储为红色、绿色、蓝色和alpha值,那么还有
color.FromArgb

暗红色为Color=Color.FromArgb(alpha,255,0,0)


编辑@Puropoix还有一个有趣的建议。

特别是在序列化时,使过程不可知通常是值得的——它不应该关心它是ARGB字符串还是命名颜色。对于这一点,可以使它不在乎它是字体、点、大小、颜色还是矩形。只需使用.NET中内置的转换器程序。(注意:您的颜色名称看起来不规则,这取决于网络处理到和从):

Dim C = System.Drawing.Color.FromName(YourColorString.Replace("Color[" , "").Replace("]", ""))
这将为您提供一个可以转换回字体、点、矩形等的字符串,具体取决于
v
的类型。要取回对象,请执行以下操作:

myColor = TypeDescriptor.GetConverter(GetType(System.Drawing.Color)) _ 
              .ConvertFromInvariantString(_text)
如果使用泛型将其封装在函数中,则它也可以不可知地解包:

 Function ConvertMyThing(Of T)(text as String) As T

    return CType(TypeDescriptor.GetConverter(GetType(T)) _ 
              .ConvertFromInvariantString(text), T)
 End Function
用法:

  myColor = ConvertMyThing(Of Color)(colorString)
ConvertToInvariantString
ToString
不同
ToString
生成调试/人性化文本,如
Color[A=99,R=99,G=19,B=255]
或类似的点、大小等。从
ConvertToInvariantString
输出的颜色仅为
99,19,255
(如果是255,则显然省略
A


对于颜色来说,这很好,因为不需要解析,不需要正则表达式,不需要拆分、连接,不需要大惊小怪和混乱。作为奖励,它将处理点,字体,矩形,大小,小数。。。System.Enum比Font更麻烦。

如果这是winforms,为什么不使用My.settings(在解决方案资源管理器中单击我的项目,单击“设置”选项卡,创建System.drawing.color类型的新设置,范围设置为user)。您可以指定一个或多个窗体的背景色以使用相关设置(在窗体打开应用程序设置的属性中,单击属性绑定,然后在弹出的对话框中为您创建的设置指定背景色)


确保在应用程序关闭时保存设置(My.settings.save)。最终用户选择的任何颜色都将在会话之间保存。

如果保存的颜色不是指定的颜色之一,它将以
颜色[a=99,R=99,G=19,B=255]的格式写入。
。您也可以为此解析字符串:

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
选项推断打开
导入System.Text.RegularExpressions
' ...
''' 
''转换格式为“color[nameOfColor]”的字符串,或
将“颜色[A=A,R=R,G=G,B=B]”更改为System.Drawing.color。
''' 
''表示颜色的字符串。
''系统、绘图、颜色。
如果无法解析颜色,则返回FallBackColor。
公共共享函数colorFromData(作为字符串)作为颜色
暗淡的背景色=颜色。黑色
如果不是s.StartWith(“颜色”,StringComparison.OrdinalIgnoreCase),则
返回背景色
如果结束
'提取括号之间的内容。
Dim re=新正则表达式(“\[(.+?)]”)
暗淡颜色名称匹配=重新匹配
如果不是colorNameMatch,则成功
返回背景色
如果结束
Dim COLORNAME=COLORNAMETCH.Groups(1).Value
“获取已知颜色的名称。
ToDo:如果频繁调用此函数,请考虑将所有颜色创建为具有较大范围的变量。
Dim AllColor=[Enum].GetNames(GetType(System.Drawing.KnownColor))
'尝试与已知颜色进行不区分大小写的匹配。
Dim-NameOfColor=AllColor.FirstOrDefault(函数(c)String.Compare(c,ColorName,StringComparison.OrdinalIgnoreCase)=0)
如果不是String.IsNullOrEmpty(颜色名称),则
返回颜色。FromName(颜色名称)
如果结束
“这不是一种命名的颜色。解析ARGB值。
re=新正则表达式(“A=(\d+).*?R=(\d+).*?G=(\d+).*?B=(\d+),RegexOptions.IgnoreCase)
Dim componentMatches=re.Match(colorName)
如果组件匹配,则成功
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
如果a>maxValue OrElse r>maxValue OrElse g>maxValue OrElse b>maxValue,则
返回背景色
如果结束
返回系统.绘图.颜色.来自argb(a,r,g,b)
如果结束
返回背景色
端函数

如果愿意,您可以抛出FormatException而不是返回回退值。

对于未来的“搜索者”来说,有一个color.Toargb和color.Fromargb,它可以转换为可序列化的整数,也可以转换为可序列化的整数。

这可能是一个老问题,但答案总是有用的:提取颜色时,将其作为RGB提取(更容易将其转换回)。例如,您可以使用: 将S设置为字符串=ctrl.BackColor.ToArgb.ToString

要将其取回,您应使用: ctrl.BackColor=Color.FromArgb(CInt(S)) 在这种情况下,您不必只是序列化它:可以将属性提取为文本、memoryFile,用于XML或任何其他情况(当您需要将此设置放在“delimeterd”行中,并在以后解析它以恢复此颜色时) 然而,美国银行
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