WPF의 공식 Win11 테마 사용법

.NET 9.0 기반 Fluent 테마 적용 방법

.NET 9.0이 출시 되고 곧 .NET 10이 나오고 있는 가운데, Win11 테마 적용 관련된 글이 이 외에는 존재하지 않더군요. 그래서 정리를 해보았습니다.


애플리케이션 전체에 Fluent 테마 적용하기

애플리케이션의 모든 창과 컨트롤에 Fluent 테마를 적용하려면, App.xaml 파일의 <Application.Resources> 섹션에 ResourceDictionary를 추가하면 됩니다. 이 방식은 가장 광범위하게 테마를 적용하는 방법입니다.

<Application 
    x:Class="YourSampleApplication.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:YourSampleApplication">
    <Application.Resources>
        <ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml" />
    </Application.Resources>
</Application>

특정 창 또는 컨트롤에만 테마 적용하기

전체 앱이 아닌 Window, UserControl, ContentControl, 또는 Border와 같은 일부 요소에만 테마를 적용하고 싶다면, 해당 요소의 <Window.Resources> 또는 <UserControl.Resources> 섹션에 ResourceDictionary에 추가하세요.

이 방법은 특정 부분에만 다른 스타일을 적용할 때 유용합니다.

<Window
    x:Class="YourSampleApplication.MainWindow"
    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"
    xmlns:local="clr-namespace:YourSampleApplication"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml" />
    </Window.Resources>
    <Grid>
        </Grid>
</Window>

Fluent 테마를 라이트(Light) 또는 다크(Dark) 모드로 고정하기

Fluent.xaml시스템 테마 설정에 따라 자동으로 라이트 또는 다크 모드로 변경됩니다. 만약 테마를 특정 모드로 고정하고 싶다면, 다음 파일 중 하나를 선택해서 사용하면 됩니다.

  • 라이트 모드 고정:

    <ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.Light.xaml" />
    
    
  • 다크 모드 고정:

    <ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.Dark.xaml" />
    

실험적인 ThemeMode API 사용하기

WPF 컨트롤에 ThemeMode라는 실험적 API가 추가되었습니다. 이 API를 사용하면 XAML에서 직접 테마를 지정할 수 있습니다.

  • ThemeMode="System": 시스템 설정에 따릅니다.

  • ThemeMode="Light": 라이트 모드로 고정합니다.

  • ThemeMode="Dark": 다크 모드로 고정합니다.

  • ThemeMode="None": Aero2 테마(기존 테마)를 사용합니다.

주의 사항: ResourceDictionary를 사용할 때는 XAML 디자이너 미리보기에서 테마가 적용된 디자인을 볼 수 있지만, ThemeMode를 사용하면 미리보기에서 기존 테마로만 보일 수 있습니다.

또한, ThemeMode 사용 시 WPF0001 경고가 발생할 수 있습니다. 이 경고를 무시하려면 프로젝트 파일(.csproj)에 <NoWarn> 속성을 추가하거나, 코드에 #pragma warning disable WPF0001를 추가해야 합니다.

  • .csproj 파일에 추가:

    XML

    <PropertyGroup>
        <NoWarn>$(NoWarn);WPF0001</NoWarn>
    </PropertyGroup>
    
    
  • 코드에 추가:

    C#

    #pragma warning disable WPF0001
    

BackDrop 관련 내용도 있긴 한데..직접 실험해보고 정리해서 올리도록 하겠습니다.

자료출처(wpf docs)

13개의 좋아요

Backdrop

사실 이 개념은 WPF 개발자라면 많이 생소한 개념입니다. 살짝 개념을 정리하고 넘어가도록하겠습니다.


Backdrop 이란?

백드롭(Backdrop)은 간단히 말해 창의 배경을 채우는 시각적 재질을 의미합니다. 기존의 불투명한 단색 배경 대신, 창 뒤의 데스크톱 화면이나 다른 앱 창을 은은하게 비춰주는 고급스러운 디자인 효과입니다. Windows 운영체제와 앱의 UI를 시각적으로 통합하고, 사용자에게 더 풍부한 경험을 제공하기 위해 사용됩니다. WPF 개발자에게는 낯설 수 있는데, 이는 WPF가 .NET 6.0 이전까지는 이러한 현대적인 시스템 백드롭 기능을 기본적으로 지원하지 않았기 때문입니다.

출처 : 제미나이


Backdrop의 종류

크게 두가지로 나뉩니다.

  • 미카(Mica)
    • 불투명한 재질로, 사용자의 데스크톱 배경화면 색상을 은은하게 반영
  • 아크릴
    • 반투명한 재질로, 창 뒤에 있는 배경이 흐릿하게 비쳐보임
    • 팝업메뉴, 사이드바, 플라이아웃 등

WPF 적용하기 앞서

  • WinUI와 달리 WPF에서는 백드롭 효과는 기본적으로 사용하지 않습니다.
  • 백드롭을 설정하기 위해선 사전에 기본 설정 해야할 것이 있습니다.
  • 기본 설정 이후 .NET 6.0 이후부터 Windows SDK를 통해 사용할 수 있는 DwmSetWindowAttribute API 호출을 통해 설정할 수 있습니다.
<ItemGroup>
    <RuntimeHostConfigurationOption Include="Switch.System.Windows.Appearance.DisableFluentThemeWindowBackdrop" Value="True" />
</ItemGroup>

or runtime config

{
  "runtimeOptions": {
    "tfm": "net9.0",
    "frameworks": [
        // specifications...   
    ],
    "configProperties": {
      "Switch.System.Windows.Appearance.DisableFluentThemeWindowBackdrop": true,
    }
  }
}

설정 코드

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent ();
        Loaded += (_, __) => EnableMicaBackdrop ();
    }

    private void EnableMicaBackdrop()
    {
        var hwnd = new WindowInteropHelper (this).Handle;
        int backdrop = (int)DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TABBEDWINDOW; // Mica

        // 시스템 백드롭 타입 설정
        DwmSetWindowAttribute (
            hwnd,
            DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE,
            ref backdrop,
            Marshal.SizeOf<int> ());
    }

    // ---- P/Invoke 정의 ----

    private enum DWMWINDOWATTRIBUTE
    {
        DWMWA_SYSTEMBACKDROP_TYPE = 38
    }

    private enum DWM_SYSTEMBACKDROP_TYPE
    {
        DWMSBT_AUTO = 0,
        DWMSBT_NONE = 1,
        DWMSBT_MAINWINDOW = 2,  // Mica
        DWMSBT_TRANSIENTWINDOW = 3,
        DWMSBT_TABBEDWINDOW = 4 // Mica Alt
    }

    [DllImport ("dwmapi.dll")]
    private static extern int DwmSetWindowAttribute(
        IntPtr hwnd,
        DWMWINDOWATTRIBUTE dwAttribute,
        ref int pvAttribute,
        int cbAttribute);
}
int backdrop = (int)DWM_SYSTEMBACKDROP_TYPE.DWMSBT_TABBEDWINDOW;

부분에 원하는 backdrop 를 선택하여 설정해주시면됩니다.

각 설정별로 했을 때의 윈도우 이미지를 찍어놓은 사진입니다.

  • AUTO = 시스템 설정에 따라
  • NONE = 미카 설정하기 전과 동일
  • MAINWINDOW = 미카 설정 무조건
  • TRANSIENTWINDOW = 창 타이틀이 반투명이 됨
  • TABBEDWINDOW = 탭 스타일의 윈도우

사실 어느정도 납득이 가는 스타일이긴한데 TABBEDWINDOW는 뭐하는 녀석이지? 라는 생각이 드실겁니다.

그래서 아래 이미지를 캡처해보았습니다.


11개의 좋아요