Using IFormattable to make your output more convenient
- Module Module1
- Sub Main()
- Dim Microsoft_example_about_Account_Number As New Account_Number(34567)
- Dim Microsoft_example_about_Tempture As New Temperature(333)
- Dim formatProvider() As FormatProvider_class = {
- New FormatProvider_class(New Globalization.CultureInfo("de-DE")),
- New FormatProvider_class(New Globalization.CultureInfo("fr-FR"))
- }
- Dim fmt = "{0:H}" & vbNewLine &
- "{1:E}" & vbNewLine &
- "{2:G}" & vbNewLine &
- "{3:G}" & vbNewLine &
- "{4:G}" & vbNewLine &
- "{5:F}" & vbNewLine
- For Each fmtProvider As FormatProvider_class In formatProvider
- Console.WriteLine("==========" & fmtProvider.CultureInfo.Name & "============")
- Console.WriteLine(String.Format(fmtProvider, fmt,
- Microsoft_example_about_Account_Number,
- 123.45,
- #2024/03/12 12:03:24#,
- New TimeSpan(12345678),
- DayOfWeek.Friday,
- Microsoft_example_about_Tempture))
- Next
- Console.WriteLine($"
- {Microsoft_example_about_Account_Number:H}
- {123.45:E}
- {#2024/03/12 12:03:24#}
- {New TimeSpan(12345678)}
- {DayOfWeek.Friday:G}
- {Microsoft_example_about_Tempture:F}
- ")
- Console.ReadKey()
- Console.WriteLine($"{New CultureInfomation_on_Windows():C}") : Console.ReadKey()
- BrowseHtml.Show($"{New CultureInfomation_on_Windows():W}")
- End Sub
- Class BrowseHtml
- Class Register_RunTime_data
- Sub New(Optional OldFilePath As Boolean = True)
- If OldFilePath Then GetHtmlFilePath()
- If String.IsNullOrEmpty(HtmlFilePath) Then
- HtmlFilePath = IO.Path.ChangeExtension(HtmlFilePath2, "html")
- End If
- End Sub
- Protected Overrides Sub finalize()
- SaveHtmlFilePath()
- End Sub
- Const Myblog = "MyBlog_7", Key = "TempFile"
- Public Shared Sub SaveHtmlFilePath()
- Interaction.SaveSetting(Reflection.Assembly.GetExecutingAssembly.GetName.Name,
- Myblog, Key, HtmlFilePath)
- End Sub
- Public Shared Sub GetHtmlFilePath()
- Try
- HtmlFilePath =
- Interaction.GetSetting(Reflection.Assembly.GetExecutingAssembly.GetName.Name,
- Myblog, Key)
- Catch ex As Exception
- End Try
- End Sub
- End Class
- Public Shared msedge_exe As String =
- IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
- "Microsoft\Edge\Application\msedge.exe")
- Public Shared HtmlFilePath1 As String = IO.Path.GetTempFileName
- Public Shared HtmlFilePath2 As String = IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
- IO.Path.GetRandomFileName)
- Shared HtmlFilePath As String
- Public Shared Sub Show(Html_content As String)
- Static For_HtmlFilePath As New Register_RunTime_data()
- Using HtmlFile As New IO.StreamWriter(HtmlFilePath, False, Text.Encoding.UTF8),
- BrowserProcess As New Process
- HtmlFile.Write(Html_content)
- HtmlFile.Flush()
- BrowserProcess.StartInfo = New ProcessStartInfo(HtmlFilePath) With {
- .Verb = "open",
- .UseShellExecute = True
- }
- If Not BrowserProcess.Start() Then Throw New Exception("error in BrowserProcess")
- End Using
- End Sub
- End Class
- '#Const trace_it = True
- Class FormatProvider_class
- Implements IFormatProvider, ICustomFormatter
- Public CultureInfo As Globalization.CultureInfo
- Sub New(cultureinfo As Globalization.CultureInfo)
- If cultureinfo Is Nothing Then
- Me.CultureInfo = Globalization.CultureInfo.CurrentCulture
- Else
- Me.CultureInfo = cultureinfo
- End If
- Trace_string = New Text.StringBuilder
- End Sub
- Function GetFormat(FormatType As Type) As Object Implements IFormatProvider.GetFormat
- Trace_string.Append(
- $"(IFormatProvider.GetFormat) FormatType={FormatType} CultureName={CultureInfo.Name}")
- Try
- Select Case FormatType
- Case GetType(ICustomFormatter)
- Return Me
- Case GetType(Globalization.NumberFormatInfo)
- Trace_string.Append($"Use NumberFormatInfo to parse/format")
- Return CultureInfo.NumberFormat
- Case GetType(Globalization.DateTimeFormatInfo)
- Trace_string.Append($"Use DateTimeFormat to parse/format")
- Return CultureInfo.DateTimeFormat
- Case Else
- Return Nothing
- End Select
- Catch ex As Exception
- Return Nothing
- Finally
- #If TRACE = trace_it Then
- Console.WriteLine(Trace_string) : Trace_string.Clear()
- #End If
- End Try
- End Function
- Public Function Format(fmt As String, arg As Object, formatProvider As IFormatProvider) As String _
- Implements ICustomFormatter.Format
- Trace_string.Append($"(ICustomFormatter.Format__IN){arg.GetType.Name,15} ")
- Try
- Select Case arg.GetType()
- Case GetType(Account_Number)
- Case GetType(Temperature)
- Case Else
- End Select
- Return CType(arg, IFormattable).ToString(fmt, Me.CultureInfo)
- Finally
- Trace_string.Append("(ICustomFormatter.Format__OUT)")
- #If TRACE = trace_it Then
- Console.WriteLine(Trace_string) : Trace_string.Clear()
- #End If
- End Try
- End Function
- Dim Trace_string As Text.StringBuilder
- End Class
- Structure Account_Number
- Implements IFormattable
- Public value As Long
- Public Sub New(value As Long)
- Me.value = value
- End Sub
- Public Overrides Function ToString() As String
- Return Me.ToString("H", Globalization.CultureInfo.CurrentCulture)
- End Function
- Public Overloads Function ToString(fmt As String) As String
- Return ToString(fmt, Globalization.CultureInfo.CurrentCulture)
- End Function
- Const ACCT_LENGTH = 12I
- Public Overloads Function ToString(fmt As String, provider As IFormatProvider) _
- As String Implements IFormattable.ToString
- #If TRACE = trace_it Then
- If provider Is Nothing Then Console.WriteLine($"fmt=({fmt}) Nothing <------------- provider")
- #End If
- Dim Bool_fmt As Boolean = fmt = "I" OrElse fmt = "H"
- If Not Bool_fmt Then Return value.ToString() & " <----- format specifier not supported"
- ' Convert argument to a string.
- Dim result As String = value.ToString()
- ' If account number is less than 12 characters, pad with leading zeroes.
- If result.Length < ACCT_LENGTH Then result = result.PadLeft(ACCT_LENGTH, "0"c)
- ' If account number is more than 12 characters, truncate to 12 characters.
- If result.Length > ACCT_LENGTH Then result = Left(result, ACCT_LENGTH)
- If fmt = "I" Then ' Integer-only format.
- Return result
- ' Add hyphens for H format specifier.
- ElseIf fmt = "H" Then ' Hypenated format.
- Return Left(result, 5) & "-" & Mid(result, 6, 3) & "-" & Right(result, 4)
- End If
- Return result
- End Function
- End Structure
- Public Const Celsius_Str = " °C"
- Public Const Fahrenheit_Str = " °F"
- Public Const Kelvin_Str = " K"
- Public Class Temperature
- Implements IFormattable
- Protected temp As Decimal
- Public Sub New(Temperature As Decimal)
- If Temperature < -273.15R Then
- Throw New Exception($"{Temperature} is less than absolute zero.")
- End If
- Me.temp = Temperature
- End Sub
- Public ReadOnly Property Celsius As Decimal
- Get
- Return temp
- End Get
- End Property
- Public ReadOnly Property Fahrenheit As Decimal
- Get
- Return temp * 9 / 5 + 32
- End Get
- End Property
- Public ReadOnly Property Kelvin As Decimal
- Get
- Return temp + 273.15D
- End Get
- End Property
- Public Overrides Function ToString() As String
- Return Me.ToString("G", Globalization.CultureInfo.CurrentCulture)
- End Function
- Public Overloads Function ToString(format As String) As String
- Return Me.ToString(format, Globalization.CultureInfo.CurrentCulture)
- End Function
- Public Overloads Function ToString(Format As String, provider As IFormatProvider) _
- As String Implements IFormattable.ToString
- If (String.IsNullOrEmpty(Format)) Then Format = "G"
- If (provider Is Nothing) Then provider = Globalization.CultureInfo.CurrentCulture
- Select Case (Format.ToUpperInvariant())
- Case "G", "C"
- Return Celsius.ToString("F2", provider) + Celsius_Str
- Case "F"
- Return Fahrenheit.ToString("F2", provider) + Fahrenheit_Str
- Case "K"
- Return Kelvin.ToString("F2", provider) + Kelvin_Str
- Case Else
- Throw New FormatException($"The {Format} format string is not supported.")
- End Select
- End Function
- End Class
- End Module
- Public Class CultureInfomation_on_Windows
- Implements IFormattable
- Protected Cultures As Globalization.CultureInfo()
- Public Sub New()
- Me.Cultures = Globalization.CultureInfo.GetCultures(Globalization.CultureTypes.AllCultures)
- End Sub
- Public Overrides Function ToString() As String
- Return Me.ToString("G", Globalization.CultureInfo.CurrentCulture)
- End Function
- Public Overloads Function ToString(Format As String, provider As IFormatProvider) _
- As String Implements IFormattable.ToString
- If (String.IsNullOrEmpty(Format)) Then Format = "G"
- If (provider Is Nothing) Then provider = Globalization.CultureInfo.CurrentCulture
- Select Case (Format.ToUpperInvariant())
- Case "G", "W"
- Dim Html_Str As New Text.StringBuilder("<!DOCTYPE html>
- <html dir=""ltr"" , lang=""zh-tw"">
- <head>
- <meta charset=""utf-8"" />
- <title>Cultures information on Windows</title>
- </head>
- <body>
- <table>
- <colgroup>
- <col />
- <col style=""background-color:chartreuse"" />
- <col />
- <col style=""background-color:chartreuse"" />
- <col />
- <col style=""background-color:chartreuse"" />
- <col />
- <col style=""background-color:chartreuse"" />
- </colgroup>
- <tr><th>index</th><th>LCID</th><th>Name</th><th>NativeName</th><th>IsNeutral</th><th>EnglishName</th></tr>
- ")
- Dim index As Int32 = 0
- For Each culture As Globalization.CultureInfo In Cultures
- index += 1
- Html_Str.Append(
- $"<tr><td>{index}</td>
- <td>{culture.LCID}</td>
- <td>{culture.Name}</td>
- <td>{culture.NativeName}</td>
- <td>{culture.IsNeutralCulture}</td>
- <td>{culture.EnglishName}</td>
- </tr>")
- Next
- Html_Str.Append("</table></body></html>")
- Return Html_Str.ToString
- Case "C"
- Dim Console_Str As New Text.StringBuilder()
- Console_Str.AppendLine("index LCID Name" &
- " NativeName NeutralCulture")
- Dim index As Int32 = 0
- For Each culture As Globalization.CultureInfo In Cultures
- index += 1
- Dim NativeName As String = culture.NativeName
- Console_Str.AppendLine(
- $"{index,5} {culture.LCID,5} {culture.Name,14} {NativeName,50} {culture.IsNeutralCulture,6}")
- Next
- Return Console_Str.ToString
- Case Else
- Throw New FormatException($"The {Format} format string is not supported.")
- End Select
- End Function
- End Class
留言
張貼留言