将 System.Windows.Forms.Font 转换为 System.Windows.Media.FontFamily 不适用于不规则样式

Converting System.Windows.Forms.Font to System.Windows.Media.FontFamily not working for irregular styles

所以,我知道有多个线程在如何在上述系统之间进行转换。我知道他们不是一对一的。但是,我希望有一种方法可以让事情正常进行。

具体有问题的字体只是示例,因为我相信其他人也有同样的问题,Segoe UI 恰好是我的默认字体。但是,当我 select Segoe UI Semibold Italic 或其他一些中间字体时,什么不起作用。

这是我的转换代码:

// Font family
FontFamilyConverter ffc = new FontFamilyConverter();
TextContent.FontFamily = (System.Windows.Media.FontFamily)
    ffc.ConvertFromString(fontDialog.Font.Name);
// Font size
TextContent.FontSize = fontDialog.Font.Size;

// Bold?
TextContent.FontWeight = (fontDialog.Font.Bold ? FontWeights.Bold : FontWeights.Normal);

// Italic?
TextContent.FontStyle = (fontDialog.Font.Italic ? FontStyles.Italic : FontStyles.Normal);

// Underline and strikethrough?
TextContent.TextDecorations = new TextDecorationCollection();
if (fontDialog.Font.Strikeout) {
    TextContent.TextDecorations.Add(TextDecorations.Strikethrough);
}
if (fontDialog.Font.Underline) {
    TextContent.TextDecorations.Add(TextDecorations.Underline);
}

// Color
TextContent.Foreground = new SolidColorBrush(
    System.Windows.Media.Color.FromArgb(fontDialog.Color.A,
                                        fontDialog.Color.R,
                                        fontDialog.Color.G,
                                        fontDialog.Color.B)
                                        );

通过使用调试器,我知道斜体 属性 设置正确,但字体没有显示为 Semibold Italic,它只是显示为 Semibold。如果(在调试器中)我将 FontFamily 更改为 "Segoe UI Semibold Italic" 那么它就可以工作了。

我是否缺少能够正确显示所有样式的内容?

谢谢。

注意:我知道大小无法正常工作。只是还没修好

这是我最终得到的结果:

对话后returns确定:

FontFamilyConverter ffc = new FontFamilyConverter();
TextContent.FontFamily = (System.Windows.Media.FontFamily) ffc.ConvertFromString(getFontName(fontDialog.Font));

辅助方法:

private List<string> limitFontList(List<string> fontList, string word) {
    // Create a new list
    var newFontList = new List<string>();

    // Go through each element in the list
    foreach (var fontFamily in fontList) {
        // If the elment contains the word
        if (fontFamily.ToLower().Contains(word.ToLower())) {
            // Add it to the new list
            newFontList.Add(fontFamily);
        }
    }

    // Return the new list if anything was put in it, otherwise the original list.
    return newFontList.Count > 0 ? newFontList :  fontList;
}

getFontName:

private string getFontName(Font font) {
    // Holds the font we want to return. This will be the original name if
    // a better one cannot be found
    string fontWanted = font.FontFamily.Name;

    // Create a new Media.FontFamily
    var family = new System.Windows.Media.FontFamily(fontWanted);

    /// Get the base font name
    string baseFont = ""; // Holds the name
    /* FamilyNames.Values will holds the base name, but it's in a collection
    ** and the easiest way to get it is to use a foreach. To the best of my
    ** knowledge, there is only ever one value in Values.
    ** E.g. If the font set is Segoe UI SemiBold Italc, gets Segoe UI.
    */
    foreach(var baseF in family.FamilyNames.Values){
        baseFont = baseF;
    }

    // If the baseFont is what we were passed in, then just return
    if(baseFont == fontWanted) {
        return fontWanted;
    }

    // Get the typeface by extracting the basefont from the name.
    // Trim removes any preceeeding spaces.
    string fontTypeface = fontWanted.Substring(baseFont.Length).Trim();


    // Will hold all of the font names to be checked.
    var fontNames = new List<string>();


    // Go through all of the available typefaces, and add them to the list
    foreach (var typeface in family.FamilyTypefaces) {
        foreach(var fn in typeface.AdjustedFaceNames) {
            fontNames.Add(baseFont + " " + fn.Value);
        }
    }

    // Limit the list to elements which contain the specified typeface
    fontNames = limitFontList(fontNames, fontTypeface);


    // If the font is bold, and the original name doesn't have bold in it (semibold?)
    if(!baseFont.ToLower().Contains("bold") && font.Bold) {
        fontNames = limitFontList(fontNames, "bold");
    }
    // In a similar manner for italics
    if (!baseFont.ToLower().Contains("italic") && font.Italic) {
        fontNames = limitFontList(fontNames, "italic");
    }

    // If we have only one result left
    if(fontNames.Count == 1) {
        return fontNames[0];
    }

    // Otherwise, we can't accurately determine what the long name is,
    // So hope whatever the short name is will work.
    return fontWanted;
}