1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Material Design Themes】トグルボンタンでダークモードに切り替える

Posted at

はじめに

Material Design Themesのベーステーマをトグルボンタンで切り替えるユーザーコントロールを作成したので、備忘録として公開します。
MVVMパターンで記述するため、CommunityToolkit.Mvvmも合わせて使用します。

image.png image.png

情報

アプリケーション

  • アプリケーション:WPFアプリケーション
  • ターゲットフレームワーク:.Net 8.0

ライブラリ

  • CommunityToolkit.Mvvm 8.2.2
  • MaterialDesignThemes 5.0.0
  • MaterialDesignColors 3.0.0

プロジェクトの作成

プロジェクト名をMaterialDesignAppsとしてプロジェクトを作成しました。
作成が完了したら、画像のようにフォルダを作成してください。
image.png

フォルダ作成ができたらMainWindowをViewsフォルダに移動してください。このとき、MainWindowの名前空間をMaterialDesignApps.Viewsに変更してください。また、App.xamlのStartupUriをViews\MainWindow.xamlに変更してください。

ライブラリのインストール

NuGetパッケージの管理からCommunityToolkit.MvvmMaterialDesignThemesMaterialDesignColorsをインストールしてください。

App.xamlの設定

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

MainWindow.xamlの設定

次に、MainWindow.xamlにStyle="{StaticResource MaterialDesignWindow}"を追加します。

Views\MainWindow.xaml
<Window ...
    Style="{StaticResource MaterialDesignWindow}">
    ...
</Window>

確認

先程のApp.xamlBaseThemeDarkに変更して、アプリケーションを起動してください。
これまでの作業に問題がなければ、背景が黒色のアプリケーションが起動されます。
これで、WPFアプリケーションでMaterial Design Themesを使用する準備が整いました。

ThemeHelper.cs

HelpersフォルダにThemeHelper.csを作成します。

Helpers\ThemeHelper.cs
using MaterialDesignColors;
using MaterialDesignThemes.Wpf;
using System.Windows;

namespace MaterialDesignApps.Helpers;

public class ThemeHelper
{
    /// <summary>
    /// BundledThemeの設定
    /// </summary>
    public static void SetBundledTheme(BundledTheme bundledTheme)
        => Application.Current.Resources.MergedDictionaries.Add(bundledTheme);

    /// <summary>
    /// BundledThemeの設定
    /// </summary>
    public static void SetBundledTheme(BaseTheme baseTheme, PrimaryColor primaryColor, SecondaryColor secondaryColor)
    {
        SetBundledTheme(new BundledTheme
        {
            BaseTheme = baseTheme,
            PrimaryColor = primaryColor,
            SecondaryColor = secondaryColor
        });
    }

    /// <summary>
    /// BaseThemeの取得
    /// </summary>
    public static BaseTheme GetBaseTheme() => GetBundledTheme()?.BaseTheme ?? BaseTheme.Light;

    /// <summary>
    /// PrimaryColorの取得
    /// </summary>
    public static PrimaryColor GetPrimaryColor() => GetBundledTheme()?.PrimaryColor ?? PrimaryColor.Blue;

    /// <summary>
    /// SecondaryColorの取得
    /// </summary>
    public static SecondaryColor GetSecondaryColor() => GetBundledTheme()?.SecondaryColor ?? SecondaryColor.Blue;

    /// <summary>
    /// BundledThemeの取得
    /// </summary>
    public static BundledTheme GetBundledTheme()
    {
        var bundledTheme = Application.Current.Resources.MergedDictionaries
                              .OfType<BundledTheme>()
                              .FirstOrDefault();
        return bundledTheme ?? new BundledTheme()
        {
            BaseTheme = BaseTheme.Light,
            PrimaryColor = PrimaryColor.Green,
            SecondaryColor = SecondaryColor.Green
        };
    }
}

ThemeSwitcherViewModel.cs

後にThemeSwitcherというユーザーコントロールを作成しますが、そのViewModelとしてThemeSwitcherViewModelを作成します。

ViewModels\ThemeSwitcherViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using MaterialDesignApps.Helpers;
using MaterialDesignThemes.Wpf;

namespace MaterialDesignApps.ViewModels;

public partial class ThemeSwitcherViewModel : ObservableObject
{
    [ObservableProperty]
    bool isDarkMode;

    /// <summary>
    /// チェックボックスの値変更時
    /// </summary>
    partial void OnIsDarkModeChanged(bool value)
    {
        var theme = ThemeHelper.GetBundledTheme();
        theme.BaseTheme = value ? BaseTheme.Dark : BaseTheme.Light;
        ThemeHelper.SetBundledTheme(theme);
    }

    /// <summary>
    /// コンストラクター
    /// </summary>
	public ThemeSwitcherViewModel()
    {
        var theme = ThemeHelper.GetBundledTheme();
        isDarkMode = theme.BaseTheme == BaseTheme.Dark;
    }

}

ThemeSwitcher.xaml

Controlsフォルダにユーザーコントロールを追加してください。コントロール名はThemeSwitcherとしました。ThmeSwitcher.xaml.csに変更はありません。
この作業が完了したら、一度プロジェクトをビルドしてください。ビルドが完了すると、Visual StudioのツールボックスにThemeSwitcherが現れます。

Controls\ThemeSwitcher.xaml
<UserControl
    x:Class="MaterialDesignApps.Controls.ThemeSwitcher"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:MaterialDesignApps.Controls"
    xmlns:vm="clr-namespace:MaterialDesignApps.ViewModels"
    mc:Ignorable="d" >
    <UserControl.DataContext>
        <vm:ThemeSwitcherViewModel/>
    </UserControl.DataContext>
    <StackPanel
        Orientation="Horizontal">
        <TextBlock
            VerticalAlignment="Center"
            Text="Light"
            Margin="0 0 10 0"/>
        <ToggleButton
            IsChecked="{Binding IsDarkMode}"/>
        <TextBlock
            VerticalAlignment="Center"
            Text="Dark"
            Margin="10 0 0 0"/>
    </StackPanel>
</UserControl>

MainWindow.xaml

Views\MainWindow.xaml
<Window
    xmlns:Controls="clr-namespace:MaterialDesignApps.Controls" 
    x:Class="MaterialDesignApps.Views.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:MaterialDesignApps.Views"
    Style="{StaticResource MaterialDesignWindow}"
    mc:Ignorable="d"
    Title="MainWindow" Height="200" Width="300">
    <Grid>
        <Controls:ThemeSwitcher
            HorizontalAlignment="Center"
            VerticalAlignment="Center"/>
    </Grid>
</Window>

起動

起動してトグルボタンによりテーマが切り替われば完成です。

最後に

この記事は備忘録として作成しました。
コードの使用によって生じるいかなる損害も、作者は一切責任を負いません。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?