WPF Material Design 라이트모드 다크모드 적용하기

by westAhn

요즘 많은 소프트웨어에서 제공되는 옵션 중 하나는 라이트 모드와 다크 모드 지원이다. 다크 모드는 사용자가 어두운 환경에서 작업하는 경우 눈의 피로도 및 시야를 보호하기 위해 주로 사용된다. 사용자에게 라이트 모드와 다크 모드 선택권을 줄 수 있도록 WPF에서 Material Design을 이용하여 코드를 작성하여 보자.

개발 툴 : Visual Studio 2022
사용 언어 : C# WPF

라이트 모드와 다크 모드 적용 결과

MaterialDesign Light모드 적용했을 때 화면
MaterialDesign Dark모드 적용했을 때 화면

▲MaterialDesignTheme5.0이상인 경우

MaterialDesign3 Light모드 적용했을 때 화면
MaterialDesign Dark모드 적용했을 때 화면

▲MaterialDesignTheme5.0미만인 경우

라이트 모드와 다크 모드 코드 작성

STEP 1
Material Design라이브러리를 설치 및 적용 한 후, App.xaml 내에서 Material Design 테마 색을 정의한다. 필자의 경우 PrimaryColor는 Orange, SecondaryColor는 LemonChiffon으로 설정하였다.

XAML
<Application x:Class="MaterialDesign3Test.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MaterialDesign3Test"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <materialDesign:CustomColorTheme BaseTheme="Light" PrimaryColor="Orange" SecondaryColor="LemonChiffon" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" /> 
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

▲MaterialDesignTheme5.0이상인 경우

XAML
<Application x:Class="MaterialDesignTest.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MaterialDesignTest"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <materialDesign:CustomColorTheme BaseTheme="Light" PrimaryColor="Orange" SecondaryColor="LemonChiffon" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

▲MaterialDesignTheme5.0미만인 경우


STEP 2
라이트, 다크 모드에 따라 화면의 배경 색과 글자 색이 변경될 수 있도록 DynamicResource를 적용하여 주고, 라이트 모드와 다크 모드 선택은 ToggleButton을 이용하여 선택할 수 있게 만들었다. 이때, ToggleButton에 Click이벤트를 추가하여 변경될 때마다 감지 할 수 있게 한다.

XAML
<Window x:Class="MaterialDesignTest.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:MaterialDesignTest"
        mc:Ignorable="d" 
        Background="{DynamicResource MaterialDesignPaper}"
        TextElement.Foreground="{DynamicResource MaterialDesignBody}"
        Title="MainWindow" Height="200" Width="350">
    <StackPanel VerticalAlignment="Center">
        <TextBlock Text="원하는 모드를 선택하세요." HorizontalAlignment="Center" FontWeight="Bold" Margin="10"></TextBlock>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBlock Text="LIGHT" Margin="10,0"></TextBlock>
            <ToggleButton x:Name="tgbtn" Click="tgbtn_Click"></ToggleButton>
            <TextBlock Text="DRAK" Margin="10, 0"></TextBlock>
        </StackPanel>
    </StackPanel>
</Window>


STEP 3
ToggleButton의 클릭 이벤트 내에서 테마에 따라 색을 반영해 주는 코드를 작성한다.

C#
private void tgbtn_Click(object sender, RoutedEventArgs e)
{
    ModifyTheme(tgbtn.IsChecked==true);
}

private static void ModifyTheme(bool isDarkTheme)
{
    var paletteHelper = new PaletteHelper();
    var theme = paletteHelper.GetTheme();

    theme.SetBaseTheme(isDarkTheme ? BaseTheme.Dark : BaseTheme.Light);
    paletteHelper.SetTheme(theme);
}       

▲MaterialDesignTheme5.0이상인 경우

C#
private void tgbtn_Click(object sender, RoutedEventArgs e)
{
    ModifyTheme(tgbtn.IsChecked==true);
}

private static void ModifyTheme(bool isDarkTheme)
{
    var paletteHelper = new PaletteHelper();
    var theme = paletteHelper.GetTheme();

    theme.SetBaseTheme(isDarkTheme ? Theme.Dark : Theme.Light);
    paletteHelper.SetTheme(theme);
}       

▲MaterialDesignTheme5.0미만인 경우

7 comments

머테리얼디자인 2024-02-21 - 11:36 오후

글 잘 보고 갑니다!

Reply
초급자 2024-04-08 - 8:02 오후

테마에는 DARK LIGHT 에 대한 정의가 포함되어 있지 않습니다.
라고 에러가 발생합니다,.

Reply
익명 2024-04-08 - 8:00 오후

테마에는 DARK LIGHT 에 대한 정의가 포함되어 있지 않습니다.

라고 에러가 발생합니다.

Reply
익명 2024-04-15 - 11:34 오후

감사합니다

Reply
초급자 2024-04-08 - 8:01 오후

테마에는 DARK LIGHT 에 대한 정의가 포함되어 있지 않습니다.

라고 에러가 밸생합니다.

조치 방법이 있나요?

Reply
westAhn 2024-04-09 - 12:54 오전

안녕하세요. 답변이 늦었네요…
혹시 설치된 MaterialDesignThemes버전이 5.0이상인가요?
최근에 5.0으로 업데이트 되면서 일부 변경된 부분이 있거든요:)

Reply
westAhn 2024-04-09 - 2:28 오전

확인해보니 MaterialDesign5.0이상 버전에서 이름이 일부 변경되었네요.
글 내용 수정하였으니 참고하여 한번 해보세요!

Reply

Leave a Comment