There used to be a {x:Static Fonts.SystemFontFamilies} in WPF that can bind to system font list very easy. However, this is gong in UWP! How stupid it is!
These days I wrote a character map UWP application, that would use system fonts, so I did some research.
In order to get system font in UWP, we must use DirectX.
Install these 3 NuGet pacakges into your project:
"SharpDX": "3.0.1", "SharpDX.Direct2D1": "3.0.1", "SharpDX.DXGI": "3.0.1"
Then create a "InstalledFont.cs" class.
Note: The following code has been modified by me. The official example code from SharpDX will blow up if it is running on Chinese system. It would get a wrong index, and blow up with an HResult error.
In this example, "Name" stands for font name. "FamilyIndex" means the index number it is in it's font family. "Index" is where it is, in all the system fonts.
GetFonts() will return all system fonts.
public class InstalledFont { public string Name { get; set; } public int FamilyIndex { get; set; } public int Index { get; set; } public static List<InstalledFont> GetFonts() { var fontList = new List<InstalledFont>(); var factory = new Factory(); var fontCollection = factory.GetSystemFontCollection(false); var familyCount = fontCollection.FontFamilyCount; for (int i = 0; i < familyCount; i++) { var fontFamily = fontCollection.GetFontFamily(i); var familyNames = fontFamily.FamilyNames; int index; if (!familyNames.FindLocaleName(CultureInfo.CurrentCulture.Name, out index)) { if (!familyNames.FindLocaleName("en-us", out index)) { index = 0; } } string name = familyNames.GetString(index); fontList.Add(new InstalledFont() { Name = name, FamilyIndex = i, Index = index }); } return fontList; } public List<Character> GetCharacters() { var factory = new Factory(); var fontCollection = factory.GetSystemFontCollection(false); var fontFamily = fontCollection.GetFontFamily(FamilyIndex); var font = fontFamily.GetFont(Index); var characters = new List<Character>(); var count = 65535; for (var i = 0; i < count; i++) { if (font.HasCharacter(i)) { characters.Add(new Character() { Char = char.ConvertFromUtf32(i), UnicodeIndex = i }); } } return characters; } }
The type "Character" stands for a particular character in the font.
public class Character { public string Char { get; set; } public int UnicodeIndex { get; set; } }
Bind to XAML:
var fontList = InstalledFont.GetFonts(); CmbFontFamily.ItemsSource = fontList;
<ComboBox Grid.Row="0" x:Name="CmbFontFamily" x:Uid="CmbFontFamily" Width="300" SelectionChanged="CmbFontFamily_OnSelectionChanged" SelectedValuePath="Name"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>
If you want to disply Unicode infomation, just use "UnicodeIndex" property.
To convert an int type to HEX in C#, just use "ToString("X")":
TxtUnicode.Text = "U+" + ch.UnicodeIndex.ToString("x").ToUpper();
Opportunity
最后一行,直接吧“x”大写不就完了。。。
Peter B
To Edi, I really like the Character Map app, but I have one request to make it better. Instead of just copying and pasting one character at a time, to be able to string a few characters together, and then copying that string of characters across to other programs via the clipboard. This would make it more useful for International languages to take into other programs. Hope you could implement my idea.
Linda
Hi. Was wondering if there is any reason why all of a sudden my systems fonts are not showing up in character map? They used to all show up. Now only the standard ones are there. I have downloaded many fonts. They show up in excel, word, my Cricut machine etc. Any insight would be greatly appreciated.