実践!Windowsアプリを作る
第2章 WPFデザイン
「第1章 WPFアプリケーション」ではWPFのアプリケーションとして指定フォルダ内のファイルを指定のファイル名でコピーするだけのシンプルなアプリケーションを作成しました。
ただ、実行して頂ければ判る通り、Windowアプリとしてのデザインは、お世辞にも良いとは言えません。
モノクロームの色彩、ワイヤーフレームかと勘違いしそうな2Dのデザイン等々…。
Windows Formsやそれ以前のMFCでもデフォルトでそれなりのデザインができていました。
まあ、設計思想としてWPFやUWP等は「XAMLで比較的自由にデザインできるので、デフォルトのデザインは超シンプルにしておいて、デザイナーが好きにデザインしてね!」と云う事なのでしょう。
とは云え、絵心の無いプログラマーとしては、あまり手を掛けずにそれなりのデザインが出来上がってくれる方が良いわけで…。
と云う訳で、今回はあまり手を掛けずにそれなりのデザインのアプリケーションに仕上げていきたいと思います。
MahApps.Metro
MahApps.MetroはWPFのアプリケーション全体をMetro風のデザインにしてくれるNuGetのパッケージです。
XAMLファイルを修正、追記が必要であったり、"MainWindow.xaml.cs"を微修正する必要はありますが、通常のデザインに必要な作業量から比べれば微々たるものです。
また、デザインがある程度決まっていますので、自身で一からデザインを考える必要も無く非常に楽です。
MahApps.Metroのインストール
基本的なインストール方法はこちらを参照してください。
- 「ソリューションエクスプローラー」の"CopyFilesWithSpecifiedName"を右クリック
- “NuGetパッケージの管理…"を選択
- 「NuGetパッケージマネージャー」で「参照」を選択
- “MahApps.Metro"を選択し、"インストール"をクリック
MainWindow.xaml.csのMahApps.Metro対応
MahApps.Metroを使用するためには、先ず、Windowクラスを継承したMainWindowクラスの親クラスをMetroWindowクラスに変更する必要があります。
“MainWindow.xaml.cs"の変更は以下のようにします。
using MahApps.Metro.Controls;
namespace CopyFilesWithSpecifiedName
{
public partial class MainWindow : MetroWindow
{
:
:
public MainWindow()
{
InitializeComponent();
:
:
}
:
:
}
}
usingディレクティブで"MahApps.Metro.Controls"を指定した上で、MainWindowのクラス宣言でMetroWindowクラスを継承するように指定するだけです。
MainWindow.xamlのMahApps.Metro対応
MahApps.Metroを使用するためには、ウィンドウのデザイン等を指定するXAMLファイル、ここでは"MainWindow.xaml"を変更します。
デフォルトではMainWindowはWindowクラスを継承していましたので、<Window...>タグを使用していました。MainWindwはMetroWindowを継承するようになりましたのでタグもそれに合わせて変更します。
<mah:MetroWindow x:Class="CopyFilesWithSpecifiedName.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CopyFilesWithSpecifiedName"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
:
:
</Grid>
</mah:MetroWindow>
<Window...>タグを<mah:MetroWindow...>タグへと変更し"xmlns:mah"属性に"http://metro.mahapps.com/winfx/xaml/controls"を追加指定します。
App.xamlのMahApps.Metro対応
最後に、"App.xaml"のMahApps.Metro対応を行います。
<Application.Resources>タグの子要素として以下のような<ResourceDictionary>を追加します。
<Application x:Class="CopyFilesWithSpecifiedName.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CopyFilesWithSpecifiedName"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
なお、"pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml"の部分でデザインテーマを選択できます。
“Light.Blue"の部分を以下のように指定できます。
前半部分については、"Light"と"Dark"の2種類から選択できます。
後半部分については、"Red", “Green", “Blue", “Purple", “Orange", “Lime", “Emerald", “Teal", “Cyan", “Cobalt", “Indigo", “Violet", “Pink", “Magenta", “Crimson", “Amber", “Yellow", “Brown", “Olive", “Steel", “Mauve", “Taupe", “Sienna"の23種類から選択できます。
デフォルトのMahApps.Metroデザイン
とりあえず現時点でMahApps.Metroデザインに変わっているはずです。
実行結果は以下の通りです。

とりあえずはタイトルバーとボーダーに色が付き、ボタンの角が丸みを帯びたデザインに変わっています。
マウスオーバーした際にはフラッシュしたり、ボタンクリック時にはボーダーが太くなったりと、それなりに見栄えが良くなっています。
この時点でのコードはこちらを参照してください。
ただ、ボタン等のコントロール類のデザインは多少良くなった程度なので、もう少し手を加えたいと思います。
Material Design In XAML Toolkit
Material Design In XAML ToolkitはWPFのアプリケーション全体をマテリアルデザイン風にしてくれるNuGetのパッケージです。
XAMLファイルの修正、追記の必要はありますが、通常のデザインに必要な作業量から比べれば微々たるものです。
また、デザインがある程度決まっていますので、自身で一からデザインを考える必要も無く非常に楽です。
Material Design In XAML Toolkitのインストール
基本的なインストール方法はこちらを参照してください。
- 「ソリューションエクスプローラー」の"CopyFilesWithSpecifiedName"を右クリック
- “NuGetパッケージの管理…"を選択
- 「NuGetパッケージマネージャー」で「参照」を選択
- “MaterialDesignThemes"を選択し、"インストール"をクリック
なお、Material Design In XAML ToolkitとMahApps.Metroを併用する場合には、"MaterialDesignThemes"と同時に"MaterialDesignThemes.MahApps"をインストールします。
因みに"MaterialDesignThemes.MahApps"をインストールすると、"MaterialDesignThemes"と"MahApps.Metro"も同時にインストールしてくれます。
MainWindow.xamlのMaterial Design In XAML Toolkit対応
Material Design In XAML Toolkitを使用するためには、ウィンドウのデザイン等を指定するXAMLファイル、ここでは"MainWindow.xaml"を変更します。
基本的には<Window...>タグの属性として以下を追加します。
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
TextElement.FontWeight="Medium"
TextElement.FontSize="14"
FontFamily="{materialDesign:MaterialDesignFont}"
MahApps.Metroと併用する場合には、<mah:MetroWindow...>タグの属性として追加します。
<mah:MetroWindow x:Class="CopyFilesWithSpecifiedName.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CopyFilesWithSpecifiedName"
mc:Ignorable="d"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
TextElement.FontWeight="Medium"
TextElement.FontSize="14"
FontFamily="{materialDesign:MaterialDesignFont}"
Title="MainWindow" Height="450" Width="800">
<Grid>
:
:
</Grid>
</mah:MetroWindow>
<Window...>タグを<mah:MetroWindow...>タグへと変更し"xmlns:mah"属性として"http://metro.mahapps.com/winfx/xaml/controls"を追加指定します。
App.xamlのMaterial Design In XAML Toolkit対応
最後に、"App.xaml"のMaterial Design In XAML Toolkit対応を行います。
先ず、<Application...>タグの"xmlns:materialDesign"属性として “http://materialdesigninxaml.net/winfx/xaml/themes"を追加します。
更に<Application.Resources>タグの子要素として以下のような<ResourceDictionary>を追加します。
<Application x:Class="CopyFilesWithSpecifiedName.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CopyFilesWithSpecifiedName"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Material Design -->
<materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="DeepPurple" SecondaryColor="Lime" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
更にMahApps.Metroと併用する場合には、MahApps.Metroの<ResourceDictionaryの記述と共にMaterial Design In XAML ToolkitとMahApps.Metroの互換性を保つための指定を追加します。
<Application x:Class="CopyFilesWithSpecifiedName.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CopyFilesWithSpecifiedName"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<!-- Theme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
<!-- Material Design -->
<materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="DeepPurple" SecondaryColor="Lime" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<!-- Material Design: MahApps Compatibility -->
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Flyout.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- MahApps Brushes -->
<SolidColorBrush x:Key="HighlightBrush" Color="{DynamicResource Primary700}"/>
<SolidColorBrush x:Key="AccentBaseColorBrush" Color="{DynamicResource Primary600}" />
<SolidColorBrush x:Key="AccentColorBrush" Color="{DynamicResource Primary500}"/>
<SolidColorBrush x:Key="AccentColorBrush2" Color="{DynamicResource Primary400}"/>
<SolidColorBrush x:Key="AccentColorBrush3" Color="{DynamicResource Primary300}"/>
<SolidColorBrush x:Key="AccentColorBrush4" Color="{DynamicResource Primary200}"/>
<SolidColorBrush x:Key="WindowTitleColorBrush" Color="{DynamicResource Primary700}"/>
<SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{DynamicResource Primary500Foreground}"/>
<LinearGradientBrush x:Key="ProgressBrush" EndPoint="0.001,0.5" StartPoint="1.002,0.5">
<GradientStop Color="{DynamicResource Primary700}" Offset="0"/>
<GradientStop Color="{DynamicResource Primary300}" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="CheckmarkFill" Color="{DynamicResource Primary500}"/>
<SolidColorBrush x:Key="RightArrowFill" Color="{DynamicResource Primary500}"/>
<SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{DynamicResource Primary500Foreground}"/>
<SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4"/>
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchBrush.Win10" Color="{DynamicResource Primary500}" />
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchMouseOverBrush.Win10" Color="{DynamicResource Primary400}" />
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.ThumbIndicatorCheckedBrush.Win10" Color="{DynamicResource Primary500Foreground}" />
</ResourceDictionary>
</Application.Resources>
</Application>
互換性のため、<ResourceDictionary...>は2つだけ追加となりますが、<SolidColorBrush...>等、結構多くの設定の追加が必要です。
Material Design In XAML ToolkitとMahApps.Metroデザイン
とりあえず現時点でMaterial Design In XAML ToolkitとMahApps.Metroを併用したデザインに変わっているはずです。
実行結果は以下の通りです。

とりあえずボタン類に色がついてかなり見栄えが良くなりました。
この時点でのコードはこちらを参照してください。
デザインの微修正
Material Design In XAML ToolkitとMahApps.Metroを併用した事で、ある程度の見栄えにする事ができました。
ただ、もう少し手を加える事ができるかと思います。
タイトルバーの修正
タイトルバーについてはMahApps.Metroによって色がついて多少は良くなってはいますが、もう少し手を入れていきたいと思います。
タイトル変更
現状、タイトルバーのタイトルは"MainWindow"となっています。
これをアプリケーション名である"CopyFilesWithSpecifiedName"に変更します。
タイトルバーのタイトルは、"MainWindow.xaml"ファイル中、<Window...>もしくは<mah:MetroWindow>タグの"Title"属性を変更します。
<mah:MetroWindow x:Class="CopyFilesWithSpecifiedName.MainWindow"
:
:
Title="CopyFilesWithSpecifiedName" Height="450" Width="800">
<Grid>
:
:
</Grid>
</mah:MetroWindow>
クローズボタン
Closeボタンを実装していますのでタイトルバーの右端のクローズボタンは不要です。
消しておきましょう。
“MainWindow.xaml"ファイル中、<Window...>もしくは<mah:MetroWindow>タグに"ShowCloseButton"属性として"False"を追加指定します。
<mah:MetroWindow x:Class="CopyFilesWithSpecifiedName.MainWindow"
:
:
Title="CopyFilesWithSpecifiedName" Height="450" Width="800" ShowCloseButton="False">
<Grid>
:
:
</Grid>
</mah:MetroWindow>
タイトルバーの色とボタンの色
現状、タイトルバーの色はMahApps.Metroのテーマで設定された"Light.Blue"、ボタン等のコントロールの色はMaterial Design In XAML ToolkitのPrimaryColorで設定された"DeepPurple"となっています。
少々、ボタンの色が鮮やかすぎる感じですので、タイトルバーの色に寄せたいと思います。
同じ色にする事も可能ですが、設定が面倒ですので、あくまでも似た色に変更と云う事で…。
基本的にはMaterial Design In XAML Toolkitの<materialDesign:BundledTheme.../>タグの"PrimaryColor"属性を変更するだけです。
今回は"LightBlue"に変更しておきます。
<Application x:Class="CopyFilesWithSpecifiedName.App"
:
:
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
:
:
<!-- Material Design -->
<materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="LightBlue" SecondaryColor="Lime" />
:
:
</ResourceDictionary.MergedDictionaries>
:
:
</ResourceDictionary>
</Application.Resources>
</Application>
Copyボタンの修正
Copyボタンが味気ないので、もう少し手を加えてみます。
ボタンの形状を両端が丸くなった形とし、内部にIconと"Copy"の文字を表示します。
ついでにツールチップも表示するようにしましょう。
ボタンの外観はこんな感じにします。
![]()
本来、ボタンの形状を変えたりするのはXAMLを使用すれば可能ですし、Iconも自作等を行ってプロジェクトに読み込ませることもできます。
ただ、MaterialDesignThemesに用意されたものを使えば容易ですので、今回はMaterialDesignThemesを使っていきます。
MaterialDesign DemoApp
MaterialDesignThemesは非常に便利ですが、用意されたデザインが豊富なので、何をどのように指定したらいいのか判り難い場合が殆どです。
そのため、サンプルとなるデザインがデモアプリとして用意されています。
MaterialDesignInXamlToolkitのページの"Releases"から"DemoApp.zip"をダウンロードします。
ダウンロードしたzipファイルを解凍し、"demo-app"->"Release"->"net6.0-windows"内の"MaterialDesignDemo.exe"を実行すると、以下のような画面が表示されます。

“Welcome to Material Design In Xaml Toolkit"の下の"EXPLORE"ボタンをクリックすると、左にナビゲーションウィンドウが表示されます。

例えば"Buttons"を選択すると、様々な種類のボタンが表示されます。

ボタンの横の"</>"をクリックすると、サンプルのボタンを表示するためのタグが表示されますので、参考にする事ができます。

Copyボタン形状指定
今回の表示したいCopyボタンに近い物としては、"Buttons-With Custom Corner Radius"中の"25/50 Radius"ですが、そのタグは以下のようになります。
<Grid
Width="{StaticResource GridWidth}">
<Button
Height="{StaticResource ButtonHeight}"
materialDesign:ButtonAssist.CornerRadius="25"
IsEnabled="{Binding DataContext.ControlsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
Style="{StaticResource MaterialDesignRaisedDarkButton}"
ToolTip="MaterialDesignRaisedDarkButton with Round Corners">
<TextBlock
Text="25/50 Radius" />
</Button>
</Grid>
このコード中、ボタンの両端を丸くするための指定は"materialDesign:ButtonAssist.CornerRadius"属性の部分ですので、Copyボタンのタグに属性の値"25″を追加します。
<Button x:Name="CopyButton" Content=" ⇒ " Margin="5,0,5,0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" IsEnabled="False" Click="CopyButton_Click"
materialDesign:ButtonAssist.CornerRadius="25"/>
本来、ボタンのコーナーの丸みは、<Button>タグ中に<Broder>タグを指定し、その属性として"CornerRadius"を設定する必要があり、結構面倒なのですが、MaterialDesignThemesを使用すれば<Button>タグの属性1つで設定できるので大変便利です。
Copyボタンのツールチップの追加
ツールチップについては、MaterialDesignThemesやMahApps.Metroは関係無く、単純に<Button>タグに"ToolsTip"属性を設定すれば良いだけです。
<Button x:Name="CopyButton" Content=" ⇒ " Margin="5,0,5,0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" IsEnabled="False" Click="CopyButton_Click"
materialDesign:ButtonAssist.CornerRadius="25"
ToolTip="ファイルを指定の名前でコピーします。" Cursor=""/>
理由は不明なのですが"Cursor"属性が自動的に付加されます。
特に問題はなさそうなので、そのままスルーして下さい。
なお、このままですと、ボタンが"Disable"の時にツールチップが表示されません。
今回は、Copyボタンが"Disable"の時にもツールチップを表示させたいので追加で"ToolTipService.ShowOnDisabled"属性に"True"を指定します。
<Button x:Name="CopyButton" Content=" ⇒ " Margin="5,0,5,0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" IsEnabled="False" Click="CopyButton_Click"
materialDesign:ButtonAssist.CornerRadius="25"
ToolTip="ファイルを指定の名前でコピーします。" ToolTipService.ShowOnDisabled="True" Cursor=""/>
CopyボタンにIconと文字列を追加
現状、Copyボタンには" ⇒ “の表示を行っていますが、これをIconと"Copy"の文字列を表示したいと思います。
具体的には、<Button>の子要素として<StackPanel>内にIconと<TextBlock>を配置します。
先ずIconですが、MaterialDesignThemesには豊富なIconが用意されています。
先ほどの"MaterialDesignDemo.exe"で左のナビゲーションウィンドウで"Icon Pack"を選択すると、利用できるIconがリストアップされます。
ただ、数が多いので、左下の"Search"で検索すると良いでしょう。
今回は"File"で検索し"FileMoveOutline"Iconをクリックします。
“Usage:"にIconのタグが表示されますので、"Copy To Clipboard"ボタンでタグをコピーし、"MainWindow.xaml"ファイルに反映します。
![]()
Iconと文字列をセットしたCopyボタンのタグは以下のようになります。
なお"Content"属性は不要となりますので削除しておきます。
<Button x:Name="CopyButton" Margin="5,0,5,0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" IsEnabled="False" Click="CopyButton_Click"
materialDesign:ButtonAssist.CornerRadius="25"
ToolTip="ファイルを指定の名前でコピーします。" ToolTipService.ShowOnDisabled="True" Cursor="">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="FileDocumentArrowRightOutline" />
<TextBlock Text="Copy"/>
</StackPanel>
</Button>
Closeボタンの修正
Closeボタンについては、表示する文字列にIconを追加します。
MaterialDesignThemesの"Icon Pack"から選択しようと思ったのですが、ピンとくるIconが無かったので、MahApps.Metroが提供するIconを使用する事にします。
以下のようなボタンにしたいと思います。
![]()
MahApps.Metro.IconPacks
MahApps.Metroは、IconとしてMahApps.Metro.IconPacksを提供しています。
MahApps.Metroと同様に「NuGetパッケージマネージャー」でMahApps.Metro.IconPacksをインストールします。
![]()
MahApps.Metro.IconPacksはMaterialDesignThemesの"Icon Pack"以上にIconの数が多いため、選択には専用のブラウザが提供されています。
こちらから"Releases"をクリックし、"IconPacks.Browser-net50-v1.0.0.zip"をダウンロードします。
ダウンロードしたファイルを解凍し、"IconPacks.Browser.exe"を実行すると、Iconのリストが表示されます。
![]()
Closeボタン用Iconの選択
MahApps.Metro.IconPacksが提供するIconの数は多いので、"IconPacks.Browser.exe"の右上の検索欄を使用し、候補を絞る事ができます。
今回は、"Exit"で候補を絞り、適当なIconを選択します。
上部に"<> {} …"等の記号が表示されますので、XAML用には"<>"をクリックし、タグをコピーします。
MahApps.Metro.IconPacksの適用
MahApps.Metro.IconPacksを使用するためには、先ず"MainWindow.xaml"ファイル中、<Window...>もしくは<mah:MetroWindow>タグに"xmlns:iconPacks"属性として"http://metro.mahapps.com/winfx/xaml/iconpacks"を追加します。
その後、<Button>の子要素として"IconPacks.Browser.exe"でコピーしたタグを追加します。
結果として"MainWindow.xaml"ファイルのCloseボタンは以下のようなコードとなります。
なお、<Button>タグの"Content"属性は不要となりますので削除します。
<mah:MetroWindow x:Class="CopyFilesWithSpecifiedName.MainWindow"
:
:
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
Title="CopyFilesWithSpecifiedName" Height="450" Width="800" ShowCloseButton="False">
<Grid>
:
:
<Button x:Name="CloseButton" Margin="0,5,5,5" Grid.Row="3" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Click="CloseButton_Click">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconVaadinIcons Kind="Exit" />
<TextBlock Text="Exit"/>
</StackPanel>
</Button>
</Grid>
</mah:MetroWindow>
リストボックスの装飾
リストボックスについては、MahApps.Metroを導入した時点で枠線が削除されたデザインになったため、ファイルが追加されるまではその範囲が判りません。
これでは少々不便なため、リストボックスの範囲が判るように枠線とバックグラウンド色を追加してみます。
- 「ドキュメントアウトライン」で"FromListBox"を選択
- 「プロパティ」で"ブラシ"の"Background"を選択
- “エディター"で"⇆"に"#4C03A9F4″を入力
- 「プロパティ」で"ブラシ"の"BorderBrush"を選択
- “エディター"で"⇆"に"#FF03A9F4″を入力
- 「プロパティ」で"外観"の"∨"以下を表示
- “BorderThickness"の項目全てに"1″を入力
修正後ののデザイン
タイトルバーとCopyボタン、Closeボタン、リストボックス修正後ののデザインは以下のようになります。

ダイアログボックスの変更
メインウィンドウのデザインはかなりマシになったかと思いますが、ダイアログボックスのデザインは元のままです。

これでは中途半端です。
なので、MahApps.MetroかMaterialDesignThemesを使用したダイアログボックスの表示を行いたいと思います。
ただ、MaterialDesignThemesを使用したダイアログボックスの表示についてはコードの量が多くなりますので現時点ではMahApps.Metroを使用したダイアログボックスの表示を行いたいと思います。
MahApps.Metroのダイアログボックス
MahApps.Metroでのダイアログボックスの表示は簡単です。
現状、MessageBox.Show("コピーしました。");としてダイアログボックスを表示していた部分をawait
this.ShowMessageAsync("コピー",
"コピーしました。");等のように変更するだけです。
なお、非同期関数コールですので、このメソッドをコールしているメソッドも非同期にする必要があります。
例えば、"MainWindow.xaml.cs"ファイル内、MainWindowクラスのメソッド"CopyButton_Click"は以下のようになります。
private async void CopyButton_Click(object sender, RoutedEventArgs e)
{
CopyButton.IsEnabled = false;
var rc = fileList.CopyFiles();
if (rc < 0)
{
await this.ShowMessageAsync("エラー", fileList.Message);
}
else
{
await this.ShowMessageAsync("コピー", "コピーしました。");
}
CopyButton.IsEnabled = true;
}
メソッドの宣言部分にasyncを追加している事に注意して下さい。
表示されるダイアログボックスは以下のようになります。

メインウィンドウの幅一杯に表示され、少々イメージと変わっています。
所謂、Modern UIと呼ばれるデザインですね。
ついでにMainWindowクラスの"FromButton_Click"メソッド中のMessageBox.Showメソッドも変えておきます。
private async void FromButton_Click(object sender, RoutedEventArgs e)
{
using (var openFolderDialog = new CommonOpenFileDialog()
{
Title = "コピー元フォルダを選択してください",
IsFolderPicker = true,
})
{
if (openFolderDialog.ShowDialog() == CommonFileDialogResult.Ok)
{
var sourceDir = openFolderDialog.FileName;
int rc = fileList.SetSourceDir(sourceDir);
if (rc < 0)
{
await this.ShowMessageAsync("エラー", fileList.Message);
}
else
{
FromTextBox.Text = sourceDir;
CopyButton.IsEnabled = (rc > 0);
}
}
}
}
まとめ
これで今回のWPFアプリケーションのデザインの修正については終わりにしたいと思います。
一応、修正前のデザインと比べ、それなりの見栄えになったかと思います。
とは云えMahApps.MetroにもMaterialDesignThemesにも上記で使用した機能以外にも様々な機能がてんこ盛りです。
使い熟せるようになればアプリケーションもグッと見栄えが良くなる事でしょう。
最終的なコードはこちらを参照してください。
実践!Windowsアプリを作る
- 第1章 WPFアプリケーション
- 第2章 WPFデザイン
- 第3章 機能更新
- 第4章 おまけ
