I've got a combo box, which allows user to select the FontFamily for some control. The combo box is populated using FrameworkElementFactory, which essentially creates a text box for each font family. Each text box print the font family name, using that font typeface. The combo box data is tied to the Fonts.SystemFontFamilies for the list of font families.
Somehow, one of the font family can't be used. An exception "Unable to find the specified file." is throw every time the combo box show its drop down list, resulted in several error dialog box, and the combo box rendered unusable. I guess the font file is corrupted somehow.
The question is: How do I catch the exception above, so I could skip that corrupted font family, and still display the remaining good fonts ?
- My guess is that the exception happen when FrameworkElementFactory "manufacture" the text box, or when the text box is rendered on screen. Either case, that means I have to somehow hook my exception handling to the FrameworkElementFactory.
- Otherwise, I have to find some validation method to makesure all fonts in SystemFontFamilies are usable. This is less desirable as there are something like 257 font families, and most of the time user probably won't use the combo at all.
Below is the code in populate the combo box data and template:
private void populateFontFamily(ComboBox cb)
{
// set up item factory for the combo box
var binding = new Binding() { Path = new PropertyPath("Source") };
var itemFactory = new FrameworkElementFactory(typeof(TextBlock));
itemFactory.SetBinding(TextBlock.TextProperty, binding);
itemFactory.SetBinding(TextBlock.FontFamilyProperty, binding);
itemFactory.SetValue(TextBlock.FontSizeProperty, 12.0);
// set the item template and item data source
cb.ItemTemplate = new DataTemplate() { VisualTree = itemFactory };
cb.ItemsSource = Fonts.SystemFontFamilies;
// fast loading (virtual panel)
var panelFactory = new FrameworkElementFactory(typeof(VirtualizingStackPanel));
panelFactory.SetValue(VirtualizingStackPanel.WidthProperty, 150.0);
cb.ItemsPanel = new ItemsPanelTemplate(panelFactory);
}