将 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;
}
所以,我知道有多个线程在如何在上述系统之间进行转换。我知道他们不是一对一的。但是,我希望有一种方法可以让事情正常进行。
具体有问题的字体只是示例,因为我相信其他人也有同样的问题,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;
}