Displaying FontFamily in Combobox

…衆ロ難τιáo~ 提交于 2020-01-01 09:50:12

问题


My goal is to manipulate the text-styles of my application via DependencyProperties. I got a diagram in which the texts are to be manipulated in size, fontfamily, color, etc. So I'd like to use an interface similar to a rich text editor like Word.

I'm using this code in my TextStyleVM http://shevaspace.blogspot.com/2006/12/i-have-some-fun-with-formattedtext_14.html

So I have a FontFamilyProperty and a Getter and Setter for it:

        public static DependencyProperty FontFamilyProperty =
            DependencyProperty.Register(
                "FontFamily",
                typeof(FontFamily),
                typeof(OutlinedText),
                new FrameworkPropertyMetadata(
                   SystemFonts.MessageFontFamily,
                   FrameworkPropertyMetadataOptions.AffectsRender |
                   FrameworkPropertyMetadataOptions.AffectsMeasure),
                      new ValidateValueCallback(IsValidFontFamily)); 

  public FontFamily FontFamily
    {
        get { return (FontFamily)base.GetValue(FontFamilyProperty); }
        set { base.SetValue(FontFamilyProperty, value); }
    }

Then there is a ToStyle method, which sets the style for the labels of the diagram, which are to be manipulated:

        Style style = new Style();
        Binding fontFamilyBinding = new Binding("FontFamily");
        fontFamilyBinding.Source = this;
        Setter fontFamilySetter = new Setter();
        fontFamilySetter.Property = TextBlock.FontFamilyProperty;
        fontFamilySetter.Value = fontFamilyBinding;
        style.Setters.Add(fontFamilySetter);

        return style;

Now this works for a TextBox. The textbox displays the current FontFamily, and if I enter a new, valid FontFamily like Arial into the textbox the FontFamily of the labels are changed.

However, what I'd like to have is a combobox, which displays the SystemFonts and where I can choose one FontFamily for my labels. However, the binding doesn't seem to work. Neither the system fonts nor the current fonts of the labels are displayed. The combobox is just empty.

This is my xaml:

            <r:RibbonLabel Content="FontFamily" />
            <!--these do not work-->
            <r:RibbonComboBox SelectedItem="{Binding FontFamily}"/>
            <r:RibbonComboBox ItemsSource="{Binding FontFamily}"/>
            <!--this works-->
            <r:RibbonTextBox Text="{Binding FontFamily}"/>

Now, I assume I have to set a different Setter for a ComboBox in the ToStyle Method. But I have no clue, which one. Maybe someting like this:

            fontFamilySetter.Property = ComboBox.ItemSource;

However, if I set that Property, the TextBox still works. So is this the wrong place to start at? I'd also be grateful if someone could hint me to some documentation about using these Style-, Setter-, Binding-key-words, which are used in the ToStyle method, since this is somebody elses code I'm working with.


回答1:


ItemsSource here expects a collection; e.g. Fonts.SystemFontFamilies

<ComboBox ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}"/>

Actually, here's a very nice link covering font selection:

http://www.hanselman.com/blog/LearningWPFWithBabySmashCustomerFeedbackAndAWPFFontComboBox.aspx

Scott Hanselman even shows how to render each font item in combobox with it's own font family.


Added per OP comment.

Here's an example of binding to dependency property. Property is named "MyFontFamily" to avoid collision with existing Window's property. Sorry, no Ribbon controls (I have bare 3.5 sp1).

Window1.xaml

<Window
    x:Class="SimpleWpf.Window1"
    x:Name="ThisWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Orientation="Vertical">
        <ComboBox
            SelectedItem="{Binding MyFontFamily, ElementName=ThisWindow}"
            ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}"/>
        <TextBlock
            Text="Lazy dog jumper"
            FontFamily="{Binding MyFontFamily, ElementName=ThisWindow}"
            FontSize="24"/>
    </StackPanel>
</Window>

Window1.xaml.cs

public partial class Window1 : Window
{
    // ...

    public static readonly DependencyProperty MyFontFamilyProperty =
        DependencyProperty.Register("MyFontFamily",
        typeof(FontFamily), typeof(Window1), new UIPropertyMetadata(null));
}



回答2:


A just in Xaml solution with fonts sorted in alphabetical order:

<Window x:Class="WpfFontsComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        Height="350" Width="525">
    <Window.Resources>
        <CollectionViewSource x:Key="SortedFontsCollection" Source="{Binding Source={x:Static Fonts.SystemFontFamilies}}" >
            <CollectionViewSource.SortDescriptions>
                <ComponentModel:SortDescription PropertyName="Source" />
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <StackPanel>
        <Label Content="42" FontFamily="{Binding ElementName=comboBoxFonts, Path=SelectedItem}" />
        <ComboBox x:Name="comboBoxFonts" ItemsSource="{Binding Source={StaticResource SortedFontsCollection}}" />
    </StackPanel>
</Window>




回答3:


A great Font Combobox for WPF can be found here:

CodeProject.com: A XAML-Only Font ComboBox

It is pure XAML, can be just copied/pasted and even sorts the fonts properly. The article also describes nicely all the gotchas encountered and how to solve them.



来源:https://stackoverflow.com/questions/2950078/displaying-fontfamily-in-combobox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!