在.NET中将String转换为System.Color

时间:2014-02-08 18:43:56

标签: .net vb.net

美好的一天,我正在尝试在VB.NET上创建这个应用程序,用户可以在其中更改应用程序的背景颜色,当应用程序关闭颜色应该保存为XML。节约是件小事,但现在真正的困境是如何将字符串"Color[white]"转换为System.Color

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

先谢谢。

7 个答案:

答案 0 :(得分:5)

您熟悉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)

编辑... @Plutonix也有一个有趣的建议。

答案 1 :(得分:3)

如果您保存的颜色不是指定颜色之一,则会以Color [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

如果您愿意,可以抛出FormatException而不是返回一个后备值。

答案 2 :(得分:2)

特别是在序列化时,通常有必要使该过程不可知 - 它不应该关心它是ARGB字符串还是命名颜色。就此而言,可以不关心它是字体,点,大小,颜色还是矩形。只需使用.NET内置的Converter程序即可。 (注意:您的颜色名称看起来不规则,这取决于NET处理To和From):

_text = TypeDescriptor.GetConverter(v.GetType).ConvertToInvariantString(v)

这将为您提供一个字符串,可以将其转换回字体,点,矩形等,具体取决于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(显然省略了A如果它是255)。

对于Color,它很棒,因为不需要解析,没有RegEx,没有拆分,加入,没有大惊小怪和没有muss。作为奖励,它将处理Point,Font,Rectangle,Size,Decimal ...... System.Enum比Font更麻烦。

答案 3 :(得分:2)

仅限未来&#34;搜索者&#34;有一个color.Toargb和color.Fromargb可以转换成一个可序列化的整数。

答案 4 :(得分:1)

Dim C = System.Drawing.Color.FromName(YourColorString.Replace("Color[" , "").Replace("]", ""))

答案 5 :(得分:0)

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

确保在应用程序关闭时保存设置(My.Settings.save)。无论最终用户选择哪种颜色,都将在会话之间保存。

答案 6 :(得分:0)

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

要取回它,你应该使用:     ctrl.BackColor = Color.FromArgb(CInt(S)) 在这种情况下,您不必只是序列化它:可以将属性提取为文本,memoryFile,在XML中使用或任何其他情况(当您需要将此设置放在“delimeterd”行中时,并解析它后来得到这种颜色) 尽管如此,你问题中描述的BackColor更像是一个设置,所以,考虑使用My.Settings并在关闭之前保存它,如Dom Sinclair(上图)的答案所述,这可能是一个更好的方法