C# avalonia没有内置FontChooser,自己实现一个就行了。增加了预览功能。

FontChooser类

    public class FontChooser : UserControl
    {
        public static readonly StyledProperty<FontFamily> SelectedFontFamilyProperty =
            AvaloniaProperty.Register<FontChooser, FontFamily>(nameof(SelectedFontFamily), new FontFamily("Segoe UI"));

        public static readonly StyledProperty<FontWeight> SelectedFontWeightProperty =
            AvaloniaProperty.Register<FontChooser, FontWeight>(nameof(SelectedFontWeight), FontWeight.Normal);

        public static readonly StyledProperty<FontStyle> SelectedFontStyleProperty =
            AvaloniaProperty.Register<FontChooser, FontStyle>(nameof(SelectedFontStyle), FontStyle.Normal);

        public static readonly StyledProperty<double> SelectedFontSizeProperty =
            AvaloniaProperty.Register<FontChooser, double>(nameof(SelectedFontSize), 12.0);

        public FontFamily SelectedFontFamily
        {
            get => GetValue(SelectedFontFamilyProperty);
            set => SetValue(SelectedFontFamilyProperty, value);
        }

        public FontWeight SelectedFontWeight
        {
            get => GetValue(SelectedFontWeightProperty);
            set => SetValue(SelectedFontWeightProperty, value);
        }

        public FontStyle SelectedFontStyle
        {
            get => GetValue(SelectedFontStyleProperty);
            set => SetValue(SelectedFontStyleProperty, value);
        }

        public double SelectedFontSize
        {
            get => GetValue(SelectedFontSizeProperty);
            set => SetValue(SelectedFontSizeProperty, value);
        }

        static FontChooser()
        {
            TemplateProperty.OverrideDefaultValue<FontChooser>(CreateControlTemplate());
        }

        private static IControlTemplate CreateControlTemplate()
        {
            return new FuncControlTemplate<FontChooser>((control, scope) =>
            {
                var panel = new StackPanel
                {
                    Spacing = 6,
                    Margin = new Thickness(5)
                };

                // 1. 字体列表
                panel.Children.Add(new TextBlock { Text = "字体:" , FontSize = 14});
                var fontCombo = new ComboBox
                {
                    ItemsSource = FontManager.Current.SystemFonts.OrderBy(x => x.Name).ToList(),
                    Width = 250
                };
                fontCombo[!!ComboBox.SelectedItemProperty] = control[!!FontChooser.SelectedFontFamilyProperty];
                panel.Children.Add(fontCombo);

                // 2. 字重
                panel.Children.Add(new TextBlock { Text = "字重:", FontSize = 14 });
                var weightCombo = new ComboBox
                {
                    ItemsSource = Enum.GetValues(typeof(FontWeight)).Cast<FontWeight>().ToList(),
                    Width = 250
                };
                weightCombo[!!ComboBox.SelectedItemProperty] = control[!!FontChooser.SelectedFontWeightProperty];
                panel.Children.Add(weightCombo);

                // 3. 字形
                panel.Children.Add(new TextBlock { Text = "字形:", FontSize = 14 });
                var styleCombo = new ComboBox
                {
                    ItemsSource = Enum.GetValues(typeof(FontStyle)).Cast<FontStyle>().ToList(),
                    Width = 250
                };
                styleCombo[!!ComboBox.SelectedItemProperty] = control[!!FontChooser.SelectedFontStyleProperty];
                panel.Children.Add(styleCombo);

                // 4. 字号
                panel.Children.Add(new TextBlock { Text = "字号:", FontSize = 14 });
                var sizeBox = new NumericUpDown
                {
                    Minimum = 6,
                    Maximum = 72,
                    Increment = 1,
                    Width = 100
                };
                sizeBox.GetObservable(NumericUpDown.ValueProperty)
                              .Subscribe(v => { if (v.HasValue) control.SelectedFontSize = (double)v.Value; });
                control.GetObservable(FontChooser.SelectedFontSizeProperty)
                    .Subscribe(sv => sizeBox.Value = (decimal?)sv); 
                panel.Children.Add(sizeBox);

                // 5. 预览
                panel.Children.Add(new TextBlock { Text = "实时预览:" , FontSize = 14 });
                var preview = new TextBlock
                {
                    Text = "示例文字 AaBbCc 123",
                    Margin = new Thickness(0, 5),
                    Padding = new Thickness(5),
                    Background = Brushes.WhiteSmoke
                };

                // 实时绑定预览
                preview[!!TextBlock.FontFamilyProperty] = control[!!FontChooser.SelectedFontFamilyProperty];
                preview[!!TextBlock.FontWeightProperty] = control[!!FontChooser.SelectedFontWeightProperty];
                preview[!!TextBlock.FontStyleProperty] = control[!!FontChooser.SelectedFontStyleProperty];
                preview[!!TextBlock.FontSizeProperty] = control[!!FontChooser.SelectedFontSizeProperty];

                panel.Children.Add(preview);

                return panel;
            });
        }
    }

FontChooser.axaml代码

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Height="400" Width="300"
        x:Class="AvaloniaUI.FontChooser"
        Title="FontChooser">
        <FontChooser></FontChooser>
</Window>

FontChooser.axaml.cs代码

using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using System;

namespace AvaloniaUI;

public partial class FontChooser : Window
{
    public FontChooser()
    {
        InitializeComponent();
    }
}

运行效果

image

 

posted on 2025-08-05 13:51  dalgleish  阅读(7)  评论(0)    收藏  举报