Як встановити шрифт за замовчуванням для програми WPF?


76

Я хочу мати можливість визначити сімейство шрифтів для моєї програми WPF. Бажано використовувати словник ресурсів як тему, на яку посилаються App.xaml. Я спробував створити Styleнаступне:

<Style TargetType="{x:Type Control}">
    <Setter Property="FontFamily" Value="Segoe UI" />            
</Style>

Але це не працює. Встановлення типу TextBlockпрацює для більшості елементів керування, але є кілька елементів керування, де це не застосовується.

Я знаю, що ви можете встановити шрифт у вікні, і всі дочірні елементи цього вікна успадкують шрифт. Але я думаю, що будь-яке діалогове вікно повернеться до шрифту за замовчуванням, що не зовсім те, що я хочу.

Будь-які ідеї?

Відповіді:


59

Припускаючи, що ваші Windowпідкласи не замінюють DefaultStyleKey, ви можете просто додати його до стилю Window, оскільки TextElement.FontFamilyPropertyце успадкована властивість:

<Style TargetType="{x:Type Window}"> 
    <Setter Property="FontFamily" Value="Segoe UI" />             
</Style> 

Вам також потрібно додати в конструктор додатків наступне після InitializeComponentвиклику:

FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
{
    DefaultValue = FindResource(typeof(Window))
});

Принцип роботи: Після завершення ініціалізації об’єкта App стиль Window, вказаний у ньому, стає стилем за замовчуванням для всіх вікон.


Це не працює, оскільки Стиль не застосовується до типів, які успадковуються від Вікна.
Матце

1
@Ray: Ваш фрагмент точно не працює. Оскільки вам потрібно використовувати клас, похідний від Window, задіяний якийсь додатковий код та / або xal.
Matze

1
@Matze: Це було дуже дивовижно, тому що я написав у своїй відповіді саме той код, який я використовую у своїх виробничих додатках. Нарешті я з’ясував, чому це вдалося мені, а не вам, і оновив свою відповідь, щоб виправити проблему. Щиро дякую, що звернули це на мою увагу.
Рей Бернс,

2
Або всередині захищеного перевизначення порожнечі OnStartup (StartupEventArgs e) вашого класу Application. Оскільки вам потрібно створити власний метод Main, щоб безпосередньо викликати InitializeComponent програми. Дякуємо за Ваші зусилля, щоб допомогти!
Матце

2
Це не спрацювало для мене. Style = (Style)FindResource(typeof(Window));Натомість я ставлю відразу після виклику InitializeComponent (), і це спрацювало для мене. Подяка переходить до avolk.parivedasolutions.com/2011/03/…
user1151923

27

Більшість запропонованих рішень не працювали для мене. Моє просте рішення:

Додайте це до App.xaml:

<Style TargetType="{x:Type Window}">
    <Setter Property="FontSize"
            Value="14" />
</Style>

Додайте це у свій конструктор MainWindow (після InitializeComponent):

Style = (Style)FindResource(typeof(Window));

12

Один простий спосіб зробити це програмно:

public MainWindow()
{
    this.FontFamily = new FontFamily("Segoe UI");
}

Цей працював у мене, відповідь XAML від Rays (щоб виправити як редактор, так і шрифт виконання)
mgear,

8

Насправді ви можете отримати повне рішення XAML, поєднуючи деякі інші відповіді тут.

Якщо викликається ваше головне вікно WinMain(те, яке ви завантажуєте перед усіма іншими), просто додайте посилання на стиль з іменем, наприкладWinAll

<Window x:Class="MyNamespace.WinMain"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    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"
    mc:Ignorable="d"
    Title="WinMain" Height="450" Width="800"
    Style="{StaticResource WinAll}">

а потім визначте свій стиль таким чином

<Style x:Key="WinAll" TargetType="{x:Type Window}">
    <Setter Property="FontFamily"
        Value="Comic Sans MS" />
    <Setter Property="FontSize"
        Value="14" />
</Style>

3
З першого погляду це може виглядати не елегантно, це найкращий спосіб для vs2015 + .net framework 4.5.2 із усіх відповідей, які я знайшов.
Вал,

1
Я вважаю, що це найелегантніша версія. Якщо використовується функція гарячого перезавантаження, якщо використовується відповідь від Джоуена, її не можна гаряче перезавантажувати. Однак за допомогою цієї відповіді легко перезавантажити, оскільки це просто трактується як звичайний стиль.
darophi

7

Я знайшов це:

TextElement.FontFamilyProperty.OverrideMetadata(
typeof(TextElement),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));

TextBlock.FontFamilyProperty.OverrideMetadata(
typeof(TextBlock),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));

-1

Спробуйте це просте обхідне рішення App.xaml(код не потрібен):

<SolidColorBrush x:Key="ForeBrush" Color="Blue" />

<Style x:Key="GenericTextStyle">
    <!-- Generic control forecolor definition -->
    <Setter Property="Control.Foreground" Value="{StaticResource ForeBrush}" />

    <!-- Add a definition for each unworking nested control -->
    <Style.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="{StaticResource ForeBrush}" />
        </Style>
    </Style.Resources>
</Style>

Просто прив’яжіть свій стиль Windows до цього. Для мене ідеально працює У вкладеному дереві потрібно визначити лише деякі властивості. Наприклад, властивість FontSizeможна вказати лише у загальному розділі.

Я не знаю, чому потрібно робити цей трюк. Це дивно, тому що мітка повинна походити від Control. Хто-небудь має про це уявлення?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.