Wie lege ich die Standardschriftart für eine WPF-Anwendung fest?

76

Ich möchte eine Schriftfamilie für meine WPF-Anwendung definieren können. Verwenden Sie vorzugsweise ein Ressourcenwörterbuch als Thema, auf das verwiesen wird App.xaml. Ich habe versucht, eine Stylewie folgt zu erstellen :

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

Das funktioniert aber nicht. Das Festlegen des Typs TextBlockfunktioniert für die meisten Steuerelemente, es gibt jedoch einige Steuerelemente, für die dies nicht gilt.

Ich weiß, dass Sie die Schriftart in einem Fenster festlegen können und alle untergeordneten Steuerelemente dieses Fensters die Schriftart erben lassen. Ich denke jedoch, dass alle Dialogfenster zur Standardschrift zurückkehren, was nicht genau das ist, was ich möchte.

Irgendwelche Ideen?

RogueX
quelle

Antworten:

59

Angenommen, Ihre WindowUnterklassen werden nicht überschrieben DefaultStyleKey, können Sie sie einfach zu Ihrem Fensterstil hinzufügen, da TextElement.FontFamilyPropertyes sich um eine geerbte Eigenschaft handelt:

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

Nach dem InitializeComponentAufruf müssen Sie Ihrem App-Konstruktor außerdem Folgendes hinzufügen :

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

So funktioniert es: Nach Abschluss der Initialisierung des App-Objekts wird der darin angegebene Fensterstil zum Standardstil für alle Fenster.

Ray Burns
quelle
Dies funktioniert nicht, da der Stil nicht auf Typen angewendet wird, die vom Fenster geerbt werden.
Matze
1
@ Ray: Dein Snippet funktioniert definitiv nicht. Da Sie eine von Window abgeleitete Klasse verwenden müssen, ist zusätzlicher Code und / oder xal beteiligt.
Matze
1
@Matze: Das war sehr rätselhaft, weil ich in meiner Antwort genau den Code geschrieben habe , den ich in meinen Produktionsanwendungen verwende. Ich habe endlich herausgefunden, warum es bei mir funktioniert hat, aber nicht bei Ihnen, und habe meine Antwort aktualisiert, um das Problem zu beheben. Vielen Dank, dass Sie mich darauf aufmerksam gemacht haben.
Ray Burns
2
Oder innerhalb der geschützten Überschreibung void OnStartup (StartupEventArgs e) Ihrer Anwendungsklasse. Weil Sie Ihre eigene Main-Methode erstellen müssen, um InitializeComponent of App direkt aufzurufen. Vielen Dank für Ihre Hilfe!
Matze
2
Das hat bei mir nicht funktioniert. Ich habe Style = (Style)FindResource(typeof(Window));stattdessen direkt nach dem Aufruf von InitializeComponent () gesetzt und das hat bei mir funktioniert. Vielen Dank an avolk.parivedasolutions.com/2011/03/…
user1151923
26

Die meisten Lösungsvorschläge haben bei mir nicht funktioniert. Meine einfache Lösung:

Fügen Sie dies zu App.xaml hinzu:

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

Fügen Sie dies in Ihren MainWindow-Konstruktor ein (nach InitializeComponent):

Style = (Style)FindResource(typeof(Window));
Jowen
quelle
12

Ein einfacher Weg, dies programmgesteuert zu tun:

public MainWindow()
{
    this.FontFamily = new FontFamily("Segoe UI");
}
Stark
quelle
Dieser hat für mich funktioniert, mit XAML von Rays Antwort (um sowohl die
Editoransicht
8

Tatsächlich können Sie hier eine vollständige XAML-Lösung erhalten, die einige der anderen Antworten kombiniert.

Wenn Ihr Hauptfenster aufgerufen wird WinMain(das, das Sie vor allen anderen laden), fügen Sie einfach einen Verweis auf einen Stil mit dem Namen zWinAll

<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}">

und definieren Sie dann Ihren Stil auf diese Weise

<Style x:Key="WinAll" TargetType="{x:Type Window}">
    <Setter Property="FontFamily"
        Value="Comic Sans MS" />
    <Setter Property="FontSize"
        Value="14" />
</Style>
Francesco B.
quelle
3
Es mag für den ersten Glace nicht elegant aussehen, es ist der beste Weg für vs2015 + .net Framework 4.5.2 aus allen Antworten, die ich gefunden habe.
Val
1
Ich finde das die eleganteste Version. Wenn die Hot-Reload-Funktion verwendet wird und die Antwort von Jowen verwendet wird, kann sie nicht im laufenden Betrieb neu geladen werden. Mit dieser Antwort ist es jedoch leicht möglich, ein Hot-Reload durchzuführen, da dies nur als normaler Stil behandelt wird.
Darophi
7

Ich habe das gefunden :

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

TextBlock.FontFamilyProperty.OverrideMetadata(
typeof(TextBlock),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));
Ehsan Zargar Ershadi
quelle
-1

Versuchen Sie diese einfache Problemumgehung in App.xaml(kein Code dahinter erforderlich):

<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>

Binden Sie einfach Ihren Windows-Stil daran. Funktioniert perfekt für mich. Im verschachtelten Baum müssen nur einige Eigenschaften definiert werden. Beispielsweise kann die Eigenschaft FontSizenur im generischen Abschnitt angegeben werden.

Ich weiß nicht, warum das notwendig ist, um diesen Trick zu machen. Es ist seltsam, weil Label von Control abgeleitet werden sollte. Hat jemand eine Idee davon?

LoxLox
quelle