【问题标题】:A WPF combobox showing FontFamilies lists garbage names显示 FontFamilies 的 WPF 组合框列出了垃圾名称
【发布时间】:2017-11-30 17:19:04
【问题描述】:

我正在尝试按照this article by Scott Hanselman 创建一个 WPF 字体下拉菜单。

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

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

【问题讨论】:

  • 不确定你所说的动态是什么意思,但我认为字母表在 char(65) 到 char(100) 的范围内,如果你超出了这个范围,比如说你认识的字体名称的第一个字符需要恢复它或你想做的其他事情..只是这个想法..
  • @johnyTee 给定一个 FontFamily,查询其属性以确定单词“Webdings”是否是人类可读的,而不是一堆奇怪的符号,然后使用 Arial 呈现文本“Webdings”

标签: c# wpf fonts


【解决方案1】:

您可以使用自定义 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();
    }
}

截图

【讨论】:

  • 我们的团队刚刚实现了这个,效果很好!非常感谢。
【解决方案2】:

字体不携带信息是否可读,因此一种简单的解决方案是简单地添加所有非可读字体(或可读)。

        InitializeComponent();
        List<string> nonReadebleFonts = new List<string>();
        nonReadebleFonts.Add("Wingdings");
        foreach (FontFamily font in Fonts.SystemFontFamilies)
        {
            ComboBoxItem boxItem = new ComboBoxItem();
            boxItem.Content = font.ToString();
            Uri s = font.BaseUri;
            if (!nonReadebleFonts.Contains(font.ToString()))
            {
                boxItem.FontFamily = font;
            }

            fontsComboBox.Items.Add(boxItem);
        }

【讨论】:

    猜你喜欢
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多