显示FontFamilies的WPF组合框列出了垃圾名称

时间:2017-11-30 17:19:04

标签: c# wpf fonts

我尝试根据this article by Scott Hanselman创建WPF字体下拉列表。

我遇到了一个问题(MS Word似乎处理得很好) - 某些字体没有适当的字符来呈现字体的名称而不会难以辨认(即Webdings,Windings,Symbol,Bookshelf Symbol 7 )。

如何动态检测到这一点,并且使用WPF,还原为像Arial这样合理的东西?

2 个答案:

答案 0 :(得分:2)

您可以使用自定义IValueConverter来设置ComboBoxItem文本的FontFamily。如果字体系列是基于符号的,则不会应用该字体。

<强> XAML

<Window x:Class="WpfApp4.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:converters="clr-namespace:WpfApp4.Views.Converters"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.Resources>
        <converters:PrintableFontFamilyConverter  x:Key="PrintableFontFamilyConverter" />
    </Grid.Resources>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <ComboBox x:Name="ComboBox" ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Source}" FontFamily="{Binding Converter={StaticResource PrintableFontFamilyConverter}}" Height="20"></TextBlock>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    <TextBox Grid.Row="1" FontFamily="{Binding ElementName=ComboBox, Path=SelectedValue}"></TextBox>
</Grid>

<强>转换器

public class PrintableFontFamilyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var fontFamily = value as FontFamily;

        if (fontFamily != null)
        {
            foreach (var typeface in fontFamily.GetTypefaces())
            {
                if (typeface.TryGetGlyphTypeface(out var glyphTypeface))
                {
                    if (glyphTypeface.Symbol)
                    {
                        return null;
                    }
                }
            }
        }

        return fontFamily;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

<强>截图

Dropdown with various font renderings

答案 1 :(得分:1)

如果字体可读或不可读,则字体不携带信息,因此一个简单的解决方案是简单地添加所有nonReadeble字体(或可读字体)。

import Data.Tree
import Text.Parsec
import Text.Parsec.String

data Nested = N [Nested] deriving (Show)

nested :: Parser Nested
nested = N <$> between (char '(') (char ')') (many nested)

parseParens :: String -> Nested
parseParens str =
  let Right result = parse (nested <* eof) "" str
  in  result