Wpf 绑定到组合框时出现SystemFontFamilies错误
我列举了fontfamilies列表并绑定到combobox,问题是当系统中存在损坏的字体时。整个应用程序将崩溃。我可以绑定到systemfontfamilies,但可以跳过显示错误的字体吗 如果对itemtemplate中的fontfamily绑定进行了注释,则以下代码可以正常运行Wpf 绑定到组合框时出现SystemFontFamilies错误,wpf,fonts,Wpf,Fonts,我列举了fontfamilies列表并绑定到combobox,问题是当系统中存在损坏的字体时。整个应用程序将崩溃。我可以绑定到systemfontfamilies,但可以跳过显示错误的字体吗 如果对itemtemplate中的fontfamily绑定进行了注释,则以下代码可以正常运行 <ComboBox x:Name="comboFonts" Grid.IsSharedSizeScope="True"
<ComboBox x:Name="comboFonts"
Grid.IsSharedSizeScope="True"
Grid.Row="0" Grid.Column="1"
ItemsSource="{Binding Source={x:Static Member=Fonts.SystemFontFamilies}}"
SelectedItem="{Binding FontFamily, Mode=TwoWay}"
HorizontalAlignment="Stretch">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="FontName"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Source}" HorizontalAlignment="Left"/>
<Label FontFamily="{Binding FallbackValue=Verdana}" HorizontalAlignment="Right">Sample</Label>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
请帮忙。谢谢,我也有同样的问题。
在richtextbox编辑器中,我用所有可用的字体族填充功能区框,并将该字体附加到组合框中的特定项,以便用户立即看到字体的外观
当系统上存在WPF无法呈现的字体时,应用程序将崩溃
查看事件查看器中的stacktrace,我注意到WPF试图实例化System.Windows.Media.GlyphTypeface类型的对象。
我发现,当我尝试自己在代码中实例化该对象(通过System.Windows.Media.Typeface类型)时,TryGetGlyphTypeface()函数会为我的特定字体设置返回false,该字体在WPF中不可用
为我解决问题的代码:
foreach (FontFamily aFontFamily in Fonts.SystemFontFamilies)
{
// Instantiate a TypeFace object with the font settings you want to use
Typeface ltypFace = new Typeface(aFontFamily, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
// Try to create a GlyphTypeface object from the TypeFace object
GlyphTypeface lglyphTypeFace;
if (ltypFace.TryGetGlyphTypeface(out lglyphTypeFace))
{
// Creation of the GlyphTypeface worked. You can use the font
RibbonGalleryItem lribItem = new RibbonGalleryItem();
lribItem.Content = aFontFamily.Source;
lribItem.FontFamily = aFontFamily;
lribGalCatFont.Items.Add(lribItem);
}
}
为了防止每次加载combobox时都必须执行此代码(因为它位于用户控件中,所以执行次数很多),我在应用程序开始时执行了一次,并将可用字体数组保存在全局变量中。好的,5年后,这里有另一个解决方案: 在
窗口中声明此代码。资源
:
<CollectionViewSource x:Key="MyFonts" Source="{Binding Source={x:Static Fonts.SystemFontFamilies}, Converter={StaticResource FontToSupportedGliphConverter}}">
<CollectionViewSource.SortDescriptions>
<componentModel:SortDescription PropertyName="Source" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<Style x:Key="FontStyle">
<Setter Property="Control.FontFamily" Value="{Binding .}" />
<Setter Property="Control.FontSize" Value="16" />
</Style>
<DataTemplate x:Key="FontTemplate">
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling" ScrollViewer.IsDeferredScrollingEnabled="True">
<TextBlock Style="{StaticResource FontStyle}" Text="{Binding .}" ToolTip="{Binding .}" />
</VirtualizingStackPanel>
</DataTemplate>
并将资源应用于组合框:
<ComboBox x:Name="FreeTextFontComboBox" Margin="10,5"
MinWidth="100" MaxWidth="110" IsEditable="True"
ItemTemplate="{DynamicResource FontTemplate}"
SelectedItem="{Binding Source={x:Static prop:Settings.Default},
Path=FreeTextFontFamily}">
<ComboBox.ItemsSource>
<Binding Source="{StaticResource MyFonts}" />
</ComboBox.ItemsSource>
</ComboBox>
但是,请注意,TryGetGlyphTypeface()
对于有效的字体系列,即复合字体,返回null
是正常的。仅仅因为它返回null
,并不一定意味着字体文件已损坏(当然,如果您依赖GlyphTypeface
本身,您必须通过分解复合字体来做更多的工作来获得它……但这不是问题的一部分)。请参阅另一个答案中的注释。这种方法将跳过有效的复合字体,以及包含损坏字体文件的字体。我们如何避免丢失某些字体?用returnList.Add(字体)在try catch
中包装代码>最后?正如我在另一篇评论中所写,当你遇到复合字体时,你需要做更多的工作才能得到真正的字体。也就是说,检查它的FamilyMaps
,找到一个合适的FontFamily
,它支持您试图呈现的Unicode代码点。是的,对于无效/损坏的字体,处理异常可以解决这一问题。不过,如果你要这么做,你至少应该告诉用户是哪种字体导致了异常,这样他们就可以修复他们的系统了。
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var list = value as IReadOnlyCollection<FontFamily>;
if (list == null)
return DependencyProperty.UnsetValue;
var returnList = new List<FontFamily>();
foreach (FontFamily font in list)
{
//Instantiate a TypeFace object with the font settings you want to use
Typeface ltypFace = new Typeface(font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
//Try to create a GlyphTypeface object from the TypeFace object
GlyphTypeface lglyphTypeFace;
if (ltypFace.TryGetGlyphTypeface(out lglyphTypeFace))
{
returnList.Add(font);
}
}
return returnList;
}
<ComboBox x:Name="FreeTextFontComboBox" Margin="10,5"
MinWidth="100" MaxWidth="110" IsEditable="True"
ItemTemplate="{DynamicResource FontTemplate}"
SelectedItem="{Binding Source={x:Static prop:Settings.Default},
Path=FreeTextFontFamily}">
<ComboBox.ItemsSource>
<Binding Source="{StaticResource MyFonts}" />
</ComboBox.ItemsSource>
</ComboBox>