下図のようなシステムフォントの一覧を表示します。(左ペインで選択したフォントを右ペインのテキストに適用しているところ)
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
みたいにすれば良い思うが、それだとフォントのタイトルが英語名で表示されてしまう。各フォントのタイトルも全部同じフォントで表示されてしまう。表示順もなんかバラバラ。
なので、
- フォントのタイトルをそのシステムの言語名で表示して、
- フォントのタイトルにそのフォントを適用して、
- シンボルフォントのタイトルが化けないようにして、
- ソートして
表示するようにしてみた。