はじめに
Material Design Themesのベーステーマをトグルボンタンで切り替えるユーザーコントロールを作成したので、備忘録として公開します。
MVVMパターンで記述するため、CommunityToolkit.Mvvmも合わせて使用します。
情報
アプリケーション
- アプリケーション:WPFアプリケーション
- ターゲットフレームワーク:.Net 8.0
ライブラリ
- CommunityToolkit.Mvvm 8.2.2
- MaterialDesignThemes 5.0.0
- MaterialDesignColors 3.0.0
プロジェクトの作成
プロジェクト名をMaterialDesignApps
としてプロジェクトを作成しました。
作成が完了したら、画像のようにフォルダを作成してください。
フォルダ作成ができたらMainWindow
をViewsフォルダに移動してください。このとき、MainWindow
の名前空間をMaterialDesignApps.Views
に変更してください。また、App.xaml
のStartupUriをViews\MainWindow.xaml
に変更してください。
ライブラリのインストール
NuGetパッケージの管理からCommunityToolkit.Mvvm
とMaterialDesignThemes
、MaterialDesignColors
をインストールしてください。
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}"
を追加します。
<Window ...
Style="{StaticResource MaterialDesignWindow}">
...
</Window>
確認
先程のApp.xaml
のBaseTheme
をDark
に変更して、アプリケーションを起動してください。
これまでの作業に問題がなければ、背景が黒色のアプリケーションが起動されます。
これで、WPFアプリケーションでMaterial Design Themesを使用する準備が整いました。
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
を作成します。
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
が現れます。
<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
<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>
起動
起動してトグルボタンによりテーマが切り替われば完成です。
最後に
この記事は備忘録として作成しました。
コードの使用によって生じるいかなる損害も、作者は一切責任を負いません。