WPF, ComboBox, FontFamilies

Of course, WPF being WPF, there’s an elegant solution to getting a ComboBox onto the screen with a set of FontFamily objects displayed in it as I wanted in my last post. I can just go and write a bit of XAML as in;

 <ComboBox ItemsSource="{Binding Source={x:Static Member=Fonts.SystemFontFamilies}}">
      <ComboBox.ItemTemplate>
      <DataTemplate>
        <TextBlock FontFamily="{Binding .}" Text="{Binding Source}"/>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>

and I’m done.

I can then go and have some other UI elements that are bound to that ComboBox for their fonts as in this textbox;

  <StackPanel>  
  <TextBox FontFamily="{Binding ElementName=comboFonts,Path=SelectedValue}"/>
  
    <ComboBox x:Name="comboFonts" ItemsSource="{Binding Source={x:Static Member=Fonts.SystemFontFamilies}}">
      <ComboBox.ItemTemplate>
      <DataTemplate>
        <TextBlock FontFamily="{Binding .}" Text="{Binding Source}"/>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>
  </StackPanel>

and so, as is so often with WPF, I end up with zero code and a thing of rare beauty 🙂

I think you can take it further and pull out the typefaces for instance;

  <StackPanel>
    <TextBox FontFamily="{Binding ElementName=comboFonts,Path=SelectedValue}" 
    FontWeight="{Binding ElementName=comboFaces,Path=SelectedValue.Weight}"
    FontStretch="{Binding ElementName=comboFaces,Path=SelectedValue.Stretch}"
    FontStyle="{Binding ElementName=comboFaces,Path=SelectedValue.Style}"/>
    <ComboBox
      x:Name="comboFonts"
      ItemsSource="{Binding Source={x:Static Member=Fonts.SystemFontFamilies}}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <TextBlock
            FontFamily="{Binding .}"
            Text="{Binding Source}"/>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>
    <!-- TODO: Tidy up this binding, couldn't find another way of dealing with the dictionary -->
    <!-- for AdjustedFaceNames 😦 -->
    <ComboBox
      x:Name="comboFaces"
      ItemsSource="{Binding ElementName=comboFonts,Path=SelectedValue.FamilyTypefaces}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <ListBox ItemsSource="{Binding AdjustedFaceNames}">
            <ListBox.ItemTemplate>
              <DataTemplate>
                <TextBlock Text="{Binding Value}"/>
              </DataTemplate>
            </ListBox.ItemTemplate>
          </ListBox>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>
  </StackPanel>

You might notice that I struggled a little when it came to AdjustedFaceNames and that all examples are only displaying system fonts, not application fonts.

Whether a user cares so much about the typeface stuff, I’m not so sure. They probably just want a setting for size, weight, underline, strikethrough, etc