Làm cách nào để đặt phông chữ mặc định cho ứng dụng WPF?


76

Tôi muốn có thể xác định họ phông chữ cho ứng dụng WPF của mình. Tốt hơn là sử dụng từ điển tài nguyên làm chủ đề được tham chiếu từ App.xaml. Tôi đã thử tạo một Styletệp như sau:

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

Nhưng điều này không hiệu quả. Đặt loại TextBlockhoạt động cho hầu hết các điều khiển nhưng có một số điều khiển không áp dụng.

Tôi biết bạn có thể đặt phông chữ trên một cửa sổ và có tất cả các điều khiển con của cửa sổ đó kế thừa phông chữ đó. Nhưng tôi nghĩ rằng bất kỳ cửa sổ hộp thoại nào cũng sẽ quay trở lại phông chữ mặc định, đó không phải là chính xác những gì tôi muốn.

Có ý kiến ​​gì không?

Câu trả lời:


59

Giả sử các Windowlớp con của bạn không ghi đè DefaultStyleKey, bạn có thể chỉ cần thêm nó vào kiểu Window của mình, vì TextElement.FontFamilyPropertylà một thuộc tính được kế thừa:

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

Bạn cũng cần thêm phần sau vào phương thức khởi tạo Ứng dụng của mình sau lệnh InitializeComponentgọi:

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

Cách hoạt động: Sau khi đối tượng Ứng dụng hoàn tất quá trình khởi tạo, kiểu Cửa sổ được chỉ định trong đó được đặt làm kiểu mặc định cho tất cả các cửa sổ.


Điều này không hoạt động vì Kiểu không được áp dụng cho các kiểu được kế thừa Cửa sổ biểu mẫu.
Kết thúc

1
@Ray: Đoạn mã của bạn chắc chắn không hoạt động. Vì bạn phải sử dụng một lớp có nguồn gốc từ Window, một số mã bổ sung và / hoặc xal có liên quan.
Matze

1
@Matze: Điều này rất khó hiểu vì những gì tôi viết trong câu trả lời của mình chính xác là mã tôi sử dụng trong các ứng dụng sản xuất của mình. Cuối cùng tôi đã tìm ra lý do tại sao nó hoạt động với tôi nhưng không phù hợp với bạn và đã cập nhật câu trả lời của tôi để khắc phục sự cố. Cảm ơn bạn rất nhiều vì đã mang đến sự chú ý của tôi.
Ray Burns,

2
Hoặc bên trong ghi đè được bảo vệ void OnStartup (StartupEventArgs e) của lớp Ứng dụng của bạn. Bởi vì bạn cần tạo phương thức Chính của riêng mình để gọi trực tiếp InitializeComponent của Ứng dụng. Cảm ơn vì những nỗ lực của bạn để giúp đỡ!
Kết thúc

2
Điều này không hiệu quả với tôi. Style = (Style)FindResource(typeof(Window));Thay vào đó, tôi đã đặt ngay sau lệnh gọi InitializeComponent () và điều đó đã hiệu quả với tôi. Nhờ đi vào avolk.parivedasolutions.com/2011/03/...
user1151923

27

Hầu hết các giải pháp được đề xuất không hoạt động với tôi. Giải pháp đơn giản của tôi:

Thêm cái này vào App.xaml:

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

Thêm điều này vào phương thức khởi tạo MainWindow của bạn (sau InitializeComponent):

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

12

Một cách đơn giản để làm điều đó theo chương trình:

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

Cái này làm việc cho tôi, với XAML từ câu trả lời Rays (để có được cả hai xem biên tập và thời gian chạy chữ đúng)
mgear

8

Trên thực tế, bạn có thể nhận được một giải pháp XAML đầy đủ kết hợp một số câu trả lời khác tại đây.

Nếu cửa sổ chính của bạn được gọi WinMain( cửa sổ bạn tải trước tất cả các cửa sổ khác), chỉ cần thêm tham chiếu đến một kiểu có tên ví dụ: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}">

và sau đó xác định phong cách của bạn theo cách này

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

3
Nó có thể trông không thanh lịch cho lần lướt đầu tiên, đó là cách tốt nhất cho vs2015 + .net framework 4.5.2, trong số mọi câu trả lời tôi tìm thấy.
Val

1
Tôi thấy đây là phiên bản thanh lịch nhất. Khi sử dụng tính năng tải lại nóng, nếu câu trả lời từ Jowen được sử dụng thì không thể tải lại nóng. Tuy nhiên với câu trả lời này, có thể dễ dàng tải lại nóng vì nó chỉ được coi như một kiểu bình thường.
darophi

7

Tôi đã tìm thấy cái này :

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

Hãy thử cách giải quyết đơn giản này trong App.xaml(không cần mã phía sau):

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

Chỉ cần ràng buộc phong cách cửa sổ của bạn với điều này. Hoạt động hoàn hảo cho tôi. Chỉ một số thuộc tính cần được xác định trong cây lồng nhau. Ví dụ, thuộc tính chỉ FontSizecó thể được chỉ định trong phần chung chung.

Tôi không biết tại sao cần thiết để làm thủ thuật này. Thật kỳ lạ vì Label phải được bắt nguồn từ Control. Bất cứ ai có bất kỳ ý tưởng về nó?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.