【问题标题】:Converting System.Windows.Forms.Font to System.Windows.Media.FontFamily not working for irregular styles将 System.Windows.Forms.Font 转换为 System.Windows.Media.FontFamily 不适用于不规则样式
【发布时间】:2015-02-03 14:33:11
【问题描述】:

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

具体有问题的字体只是示例,因为我确信其他人也有同样的问题,Segoe UI 恰好是我的默认字体。但是,当我选择 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)
                                        );

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

为了让所有样式都能正确呈现,我是否缺少一些东西?

谢谢。

注意:我知道 size 不能正常工作。只是还没修好

【问题讨论】:

  • 这里有一个类似的问题 - stackoverflow.com/questions/1297772/…
  • @MethodMan,我见过那个。它没有解决必须更改实际名称以使 WPF 控件提取正确字体的情况。我实际上已经在我的代码中使用了该线程中的方法。
  • 我明白你在说什么......那么它是否适用于这一行中的已知字体名称TextContent.FontFamily = (System.Windows.Media.FontFamily) ffc.ConvertFromString(fontDialog.Font.Name);...?
  • @MethodMan,这正是我在我发布的代码的第 3 行和第 4 行所拥有的内容。
  • 我知道这就是你所拥有的......我在问它是否第一次工作,或者与已知的fontnames 如果是这样,那么我可以更好地理解......

标签: c# wpf winforms fonts


【解决方案1】:

这是我最终得到的结果:

对话框返回OK后:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 2016-05-01
    • 2021-07-08
    • 1970-01-01
    相关资源
    最近更新 更多