【VB.NET】【WPF】システムフォントの一覧を表示する

下図のようなシステムフォントの一覧を表示します。(左ペインで選択したフォントを右ペインのテキストに適用しているところ)

VB.NET WPF システムフォントの一覧

 

XAML(特に注意して欲しいところをハイライトした)

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">

<Window.Resources>
    <local:FontFamilyTitleConverter x:Key="FontFamilyTitleConverter_Key" />
    <local:FontFamilyNameConverter x:Key="FontFamilyNameConverter_Key" />
</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5*" />
        <ColumnDefinition Width="5*" />
    </Grid.ColumnDefinitions>

    <UniformGrid Grid.Column="0">
        <ListBox Name="fontsList" Margin="0,0,0,0">
            <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock FontFamily="{Binding Converter={StaticResource FontFamilyNameConverter_Key}, Mode=OneWay}" FontSize="16"
                    Text="{Binding Converter={StaticResource FontFamilyTitleConverter_Key}, Mode=OneWay}" />
            </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </UniformGrid>

    <UniformGrid Grid.Column="1">
        <TextBox Name="textbox1" Margin="0,0,0,0" Text="" FontSize="29" TextWrapping="Wrap" />
    </UniformGrid>
</Grid>

</Window>

 

コード

Class MainWindow

Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

Me.Language = System.Windows.Markup.XmlLanguage.GetLanguage(system.Threading.Thread.CurrentThread.CurrentCulture.Name) '言語を設定

Me.fontsList.ItemsSource = Fonts.SystemFontFamilies.OrderBy(Function(n) n.Source) 'システムフォントをソートして設定

Me.textbox1.Text = "エレン・イーストのブログを今後ともよろしくお願いいたします。" & vbCrLf & vbCrLf & _
    "Thank you very much! See you!" & vbCrLf & vbCrLf & "https://elleneast.com"

End Sub



Private Sub fontsList_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles fontsList.SelectionChanged

Dim l As ListBox = CType(sender, ListBox)

Me.textbox1.FontFamily = l.SelectedItem

End Sub

End Class



'現在の言語のフォント名を返す(リストボックスのタイトルのテキスト)
Friend Class FontFamilyTitleConverter
    Implements IValueConverter

Private Function Convert(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object _
    Implements IValueConverter.Convert

Dim oFontFamily As FontFamily = value
Dim oLanguage = System.Windows.Markup.XmlLanguage.GetLanguage(culture.IetfLanguageTag) ' _Loaded で設定した言語のフォント名を返す場合

For Each oFamilyNameKeyValue In oFontFamily.FamilyNames
    If oFamilyNameKeyValue.Key is oLanguage Then '.Key.ToString --> en-us, ja-jp など。
        Return oFamilyNameKeyValue.Value '.Value --> MS 明朝、Arial など。フォントの名前。
    End If
Next

Return oFontFamily.Source

End Function



Private Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object _
    Implements IValueConverter.ConvertBack

Throw New NotImplementedException()

End Function

End Class



'リストボックスのフォントタイトルに適用するフォント名。シンボル用のフォントの場合は Courier を返す(リストボックスのフォントタイトルが化けるので)。それ以外はそのままフォントファミリー名を返す。
Friend Class FontFamilyNameConverter
    Implements IValueConverter

Private Function Convert(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object _
    Implements IValueConverter.Convert

Dim oFontFamily As FontFamily = value

If IsSymbolFont(oFontFamily) = True Then
    Return "Courier"
Else
    Return oFontFamily.Source
End If

End Function



Private Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object _
    Implements IValueConverter.ConvertBack

Throw New NotImplementedException()

End Function



'シンボル用のフォントか?
Private Function IsSymbolFont(fontFamily As FontFamily) As Boolean

Dim oGlyphTypeface As GlyphTypeface = GetFirstTypeface(fontFamily)

If oGlyphTypeface Is Nothing Then
    Return False
Else
    Return oGlyphTypeface.Symbol
End If

End Function



'フォントファミリーの最初のグリフタイプフェイスを返す
Private Function GetFirstTypeface(fontFamily As FontFamily) As GlyphTypeface

Dim oFirstTypeface As Typeface = FontFamily.GetTypefaces().First()

Dim oGlyphTypeface As GlyphTypeface = Nothing

oFirstTypeface.TryGetGlyphTypeface(oGlyphTypeface)

Return oGlyphTypeface

End Function

End Class

 

システムフォントリストの一覧を最も簡単に実現したければ

Me.fontsList.ItemsSource = Fonts.SystemFontFamilies

みたいにすれば良い思うが、それだとフォントのタイトルが英語名で表示されてしまう。各フォントのタイトルも全部同じフォントで表示されてしまう。表示順もなんかバラバラ。

なので、

  • フォントのタイトルをそのシステムの言語名で表示して、
  • フォントのタイトルにそのフォントを適用して、
  • シンボルフォントのタイトルが化けないようにして、
  • ソートして

表示するようにしてみた。

購読する
通知を受け取る対象
guest
0 Comments
Inline Feedbacks
View all comments