【WPF】ResourceDictionaryの共通定義を変更する

# 参照元となるプロジェクトの作成
まずは、参照元となる共通プロジェクト「Resources」を作成し、以下のようなファイルを作成します。

Colors.xaml（ResourceDictionary）
```xml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Color x:Key="Colors.CommonBackground">LightGray</Color>
    <Color x:Key="Colors.CommonForeground">Black</Color>
    
</ResourceDictionary>
```


Brushes.xaml（ResourceDictionary）
```xml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/Resources;component/Themes/Styles/Colors.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <SolidColorBrush x:Key="Brushes.CommonBackground" Color="{DynamicResource Colors.CommonBackground}"/>
    <SolidColorBrush x:Key="Brushes.CommonForeground" Color="{DynamicResource Colors.CommonForeground}"/>
    
</ResourceDictionary>
```

また、共通プロジェクトに基底クラスとなる「WindowBase」クラスを作成しました。
WindowBase.cs（WPFカスタムコントロール）
```cs
using System.Windows;

namespace Resources
{
    public class WindowBase : Window
    {
        static WindowBase()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowBase), new FrameworkPropertyMetadata(typeof(WindowBase)));
        }
    }
}
```
Generic.xaml
```xml
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Resources">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/Resources;component/Themes/Styles/Colors.xaml"/>
        <ResourceDictionary Source="pack://application:,,,/Resources;component/Themes/Styles/Brushes.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="{x:Type local:WindowBase}">
        <Setter Property="Background" Value="{DynamicResource Brushes.CommonBackground}"/>
        <Setter Property="Foreground" Value="{DynamicResource Brushes.CommonForeground}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:WindowBase}">
                    <Border Background="{TemplateBinding Background}">
                        <ContentPresenter />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
```

ここまでのプロジェクト構成は以下となっています。
![20220310130124.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591086/22e8f51d-d491-44ea-47ca-baae2aed3b5c.png)

# 参照するプロジェクトを作成
続いて、起動用プロジェクトを作成していきます。
起動用のプロジェクト「Main」を作成し、共通プロジェクト「Resources」を参照に追加しました。
Mainプロジェクトの初期フォーム「MainWindow」の継承元を、先ほど作成した「Resources.WindowBase」に変更しています。

その後、Mainプロジェクトの「App.xaml」に先ほど作成したResourceDictionaryを追加します。
```xml
<Application x:Class="Main.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Main"
             StartupUri="MainWindow.xaml">
    
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Resources;component/Themes/Styles/Colors.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/Resources;component/Themes/Styles/Brushes.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
        
    </Application.Resources>
</Application>

```



フォームを起動すると以下の画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591086/7441d26e-220f-bb58-3ca9-753dea0a7863.png)
※文字の表示用にテキストボックスを追加しています。

Resources.Themes.Styles.Colors.xamlで定義した色が表示されています。

それでは、起動用プロジェクトで色を再定義してみましょう。
先ほど編集した「App.xaml」に以下のように追記します。
```xml
<Application x:Class="Main.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Main"
             StartupUri="MainWindow.xaml">
    
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Resources;component/Themes/Styles/Colors.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/Resources;component/Themes/Styles/Brushes.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <Color x:Key="Colors.CommonBackground">Blue</Color>
            <Color x:Key="Colors.CommonForeground">Red</Color>
        </ResourceDictionary>
    </Application.Resources>
    
</Application>
```
背景色を青、文字色を赤にするようにしました。

それでは起動してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591086/e6ee2839-1d79-4bec-d29e-ea77bfc877ed.png)
指定した通りの色に変更することができました。
このように共通定義したものも同一Keyを指定することで再定義ができます。

今回作成したプロジェクトはGithubにアップロードしました。
以下のURLから確認できます。
https://github.com/jakucho/WPF-ResourceDictionary-Sample1