Search code examples
wpfironpythontruetypesharpdevelop

How to access an embedded font from xaml in Iron Python


I want to add an font to an WPF Iron Python application as resource. In a xaml file I want to use this font in the xml Fontfamily attribute.

MainWindow.xaml:
...
<Grid>
  <TextBox Text="ABC" FontFamily="./Fonts/#Foo"/>
</Grid>

In python code the window is loaded in the MainWindow c'tor:

MainWindow.py:

class MainWindow (Window):
   def __init__(self):
      wpf.LoadComponent(self, 'MainWindow.xaml')

In the project I add the font to an folder "Fonts" and use the build action Resource. But this approach doesn' work.


Solution

  • You will need to add the font to your text box with code. The wpf.LoadComponent() method loads the .xaml file from disk and creates the WPF window but will not look in any embedded resources for anything including fonts. The simplest way, as far as I am aware, is to load the font from disk.

    First change the build action on your font so the Copy to output directory is Always. In your example the font will be copied to bin\Debug\Fonts\ folder.

    Now you will need to give your textbox a name so you can access it via code. In your MainWindow.xaml add the x:Name attribute to your TextBox. Here I have named it textbox.

    <Grid>
        <TextBox x:Name="textbox" Text="ABC"/>
    </Grid>
    

    Now in your MainWindow class you can add a property for your textbox and in the constructor write some code to load the font from disk and apply it to your textbox. The full code is shown below.

    import wpf
    
    from System import Uri
    from System.IO import Path
    from System.Windows import Window
    from System.Windows.Media import FontFamily
    
    class MainWindow(Window):
        def __init__(self):
            wpf.LoadComponent(self, 'MainWindow.xaml')
            self.addFont()
    
        def addFont(self):
            fontDirectory = Path.GetFullPath(".\\Fonts\\")
            uri = Uri(fontDirectory)
    
            fontFamily = FontFamily(uri, "./#Foo")
            self.textbox.FontFamily = fontFamily
    
        def get_textbox(self):
            return self._textbox
    
        def set_textbox(self, value):
            self._textbox = value
    
        textbox = property(get_textbox, set_textbox)
    

    The addFont() method simply creates a Uri pointing to the directory where your font is, then creates a new FontFamily using your font's family name, then finally updates the TextBox FontFamily property.