GrapeCity.devlog

グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉の最新情報をお届けします。製品のTIPSや発売情報、イベントのお知らせなどをいち早く発信中です。

デザイン知識不要?ライブラリを利用してWindowsアプリのUIを現代風に改造

WPFがWindows Formsと比較して優れている点として、UIデザインのカスタマイズ性の高さが挙げられます。

しかし、デザインの知識もないし、どうやってUIをカスタマイズしたら良いかわからない。そんなときは、「Material Design In XAML Toolkit」のようなデザインUIライブラリを使用することで、簡単にアプリケーションのUIを現代風にカスタマイズすることができます。

今回は「ActiveReports for .NET」のWPFビューワのUIを「Material Design In XAML Toolkit」と「MahApps」という2つのライブラリを使用してカスタマイズしてみたいと思います。
※どちらもMITライセンスのライブラリです。

ActiveReports

マテリアルデザインとは

「Material Design In XAML Toolkit」はその名の通り、XAMLを使ったアプリケーションにマテリアルデザインを簡単に適用できるライブラリです。

マテリアルデザインとはGoogleが提唱しているUXデザインの体系や手法で、厳密なルールが存在し、ガイドラインも公開されておりますが、今回はライブラリで簡単にその要素を取り入れるところまでを目指します。

事前準備

まずは製品ヘルプにしたがって、WPFビューワにレポートを表示できる状態にしておきます。

ActiveReports

レポートファイルはサンプルに含まれるChainStoreUniformSlip.rdlxを使用しました。

また、WPFビューワのUIカスタマイズに必要なテンプレートファイルDefaultWPFiewerTemplates.xamlを、「ActiveReportsのインストールフォルダ\ActiveReportsNET12\Deployment\WPF」配下からコピーしてプロジェクトに追加しておきます。

f:id:GrapeCity_dev:20181127144707p:plain

NuGetからライブラリをインストールする

Nugetからカスタマイズに必要なライブラリをインストールします。「Material Design In XAML Toolkit」にはMahAppsと統合して使うためのパッケージが用意されているのでそちらを使います。

ソリューション エクスプローラーで [参照] を右クリックし、[NuGet パッケージの管理] から「MaterialDesignThemes.MahApps」を検索しインストールします。同時に依存関係のある

  • MaterialDesignThemes
  • MaterialDesignColors
  • MahApps.Metro
  • ControlzEx

もインストールされるので、必要に応じて最新版へのアップデートなどを行ってください。

f:id:GrapeCity_dev:20181129103006p:plain

テーマを設定する

インストールしたライブラリからテーマを設定するには、App.xamlに以下のコードを追加します。

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

参考情報: Getting Started · MaterialDesignInXAML/MaterialDesignInXamlToolkit Wiki · GitHub

実行すると以下のようになります。パッと見はほとんどわかりませんが、ドロップダウンやテキストボックス、ツールチップのスタイル等が変わっています。

f:id:GrapeCity_dev:20181127160043p:plain

ドロップダウンにフォーカスをあてると下線がアニメーションします。こういったアニメーションもマテリアルデザインの重要な要素です。

f:id:GrapeCity_dev:20181127161353g:plain

ツールバーのアイコンをカスタマイズする

次にツールバーのアイコンをカスタマイズしていきます。アイコンは「Material Design Icons」で公開されているものをそのまま使うこともできますが、「Material Design In XAML Toolkit」には、これらのアイコンがアイコンパックとして含まれており、通常よりも少ないコードで実装できます。

GitHubにデモアプリケーションがあるので、使えるアイコンや設定方法はそちらで紹介されています。

デモアプリケーション上でアイコンを選択すると、「Usage」の欄に対応するタグが表示されるので、これをコピーしてXAML上に貼り付ければアイコンを表示できます。どのアイコンを表示するかはKindプロパティで指定します。

ActiveReports

それでは早速ActiveReportsのWPFビューワのアイコンをこれらに差し替えていきましょう。まずはMainWindow.xamlの<Grid>の開始タグの前に以下のように使用するテンプレートを定義します。

<Window.Resources>                                
<ResourceDictionary Source="DefaultWPFViewerTemplates.xaml" />
</Window.Resources>

次に事前準備でプロジェクトに追加したDefaultWPFViewerTemplates.xamlの<ResourceDictionary>タグに以下の宣言を追加します。

<ResourceDictionary


    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

次にファイル内からbuttonToggleSidebarという名前のトグルボタンを検索し、元々記述されていた<Image>タグを以下のように<materialDesign:PackIcon>タグに置き換えます。

<!--  Sidebar button  -->
<ToggleButton
    Name="buttonToggleSidebar"
    AutomationProperties.AutomationId="ToogleSidebarButton"
    IsChecked="{Binding SidebarVisible, Mode=TwoWay}"
    IsEnabled="{Binding IsUIEnabled, Mode=OneWay}"
    Style="{StaticResource ToolButton}"
    ToolTipService.ToolTip="{Binding Source={StaticResource res},Path=Resources.ToolbarTooltip_ToggleSidebar}">
    <!-- Imageタグをコメントアウト
    <Image Style="{StaticResource ToolButtonImage}" Source="{Binding Source={StaticResource res}, Converter={StaticResource ResourceImageConverter}, Path=Resources.CmdIcon_toc}" />
    -->
    <!-- 以下を追加 -->
    <materialDesign:PackIcon
        Width="16"
        Height="16"
        Foreground="#6200EE"
        Kind="PageLayoutSidebarLeft" />
</ToggleButton>

この時点で実行すると、以下のように、サイドバーのトグルボタンのアイコンがカスタマイズされていることが確認できます。

f:id:GrapeCity_dev:20181128153528p:plain

その他のアイコンも同じ要領で差し替えてみましょう。基本的には前述の<materialDesign:PackIcon>タグのKindプロパティの値だけ変えればそれ以外の定義は同じです。詳細なコードは本記事の最後でサンプルアプリケーションを公開しているので、そちらをご覧ください。

今回の例では、ツールバーの各ボタンに対して以下のように設定しました。

ボタン名Kindプロパティ
サイドバーPageLayoutSidebarLeft
印刷Printer
ゲラモードScriptTextOutline
検索Magnify
縮小MagnifyMinus
拡大MagnifyPlus
ページ幅ArrowExpandHorizontal
ページ全体ArrowExpandAll
先頭ページArrowCollapseLeft
前ページArrowLeft
次ページArrowRight
最終ページArrowCollapseRight
戻るUndoVariant
進むRedoVariant
親レポートに戻るFileUndo
更新Refresh
キャンセルCloseCircle

ついでにカスタムのボタンも追加してみます。今回はボタンの表示だけで、クリックしたときの処理の設定方法はまた別の機会にご紹介したいと思います。

キャンセルボタンの定義の後に、以下のコードを追加します。

<Separator />
<Button
    Name="PdfExportButton"
    Content="PDFに保存"
    Style="{StaticResource MaterialDesignRaisedButton}" />
<Button
    Name="ExcelExportButton"
    Margin="10,0,0,0"
    Content="Excelに保存"
    Style="{StaticResource MaterialDesignRaisedButton}" />

実行すると以下のようにツールバーのUIをカスタマイズすることができました。

ActiveReports

ウィンドウのUIをカスタマイズする

仕上げに「MahApps.Metro」を使用して、デフォルトのウィンドウのUIをカスタマイズします。

「Material Design In XAML Toolkit」と一緒に使う場合の詳しい使用方法は以下をご覧ください。

上記のページを参考に、App.xamlを以下のように書き換えます。

<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/Colors.xaml" />
    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />

    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
    <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
    <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />

    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Fonts.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" StartPoint="1.002,0.5" EndPoint="0.001,0.5">
    <GradientStop Offset="0" Color="{DynamicResource Primary700}" />
    <GradientStop Offset="1" Color="{DynamicResource Primary300}" />
</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"
    Opacity="0.4"
    Color="{DynamicResource Primary500}" />
<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}" />

MainWindow.xamlで、<Window>タグを<metro:MetroWindow>に置き換え、以下の宣言と罫線の設定を追加します。

<metro:MetroWindow


    xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
    BorderBrush="{DynamicResource HighlightBrush}"
    BorderThickness="5"

MainWindow.xaml.csもあわせて以下のように書き換えます。

using MahApps.Metro.Controls;
・
・
    public partial class MainWindow : MetroWindow
    {

実行すると以下のようになります。アイコンにあわせてウィンドウのUIも現代風にカスタマイズ出来ました!

ActiveReports


作成したサンプルはこちらで公開しています。ActiveReports for .NET 12.0J SP2で作成されています。NuGetパッケージを復元して実行してください。

ダウンロード(zipファイル:31.8KB)


グレープシティのWPFコンポーネント

グレープシティでは今回紹介した「ActiveReports for .NET」以外にも、WPFアプリケーション開発を支援するコンポーネントを多数取り揃えています。

単体での利用はもちろん、組み合わせて利用していただくことで開発効率を飛躍的に向上させることが可能です。

以下のWebページに、弊社のWPF用開発コンポーネントのラインナップや、WPFアプリケーションの開発に役立つ情報をまとめてありますので、ぜひ一度ご覧ください。