MAUI Tips - 結合されたResourceDictionaryをコード上で取得する

# 概要
これまでXamarin.Formsで作っていたアプリを、一念発起してMAUIで作り直す中で
調べたことの備忘録。

# 環境
MacBook Air(M2 2022)
Visual Studio for Mac
MAUI
.NET 7

# 方法
結合されたResourceDictionaryの色の定義を、C#のコード上で使いたいケースを考えます。

MAUIのプロジェクトを新規作成すると、Resourcesフォルダ内のStylesに、
・Colors.xaml
・Styles.xaml
の二つのファイルが入っています。

このファイルはResourceDictionaryで、
Colors.xamlには色の定義が、Stylesには各種Controlのスタイルが定義されています。
例えばColors.xaml内には

```Colors.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<?xaml-comp compile="true" ?>
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

    <Color x:Key="Primary">#512BD4</Color>
    <Color x:Key="Secondary">#DFD8F7</Color>
    <Color x:Key="Tertiary">#2B0B98</Color>
    <Color x:Key="White">White</Color>
    <Color x:Key="Black">Black</Color>
    <Color x:Key="Gray100">#E1E1E1</Color>
    <Color x:Key="Gray200">#C8C8C8</Color>
    <Color x:Key="Gray300">#ACACAC</Color>
    <Color x:Key="Gray400">#919191</Color>
    <Color x:Key="Gray500">#6E6E6E</Color>
    <Color x:Key="Gray600">#404040</Color>
    <Color x:Key="Gray900">#212121</Color>
    <Color x:Key="Gray950">#141414</Color>
    <SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"/>
    <SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource Secondary}"/>
    <SolidColorBrush x:Key="TertiaryBrush" Color="{StaticResource Tertiary}"/>
    <SolidColorBrush x:Key="WhiteBrush" Color="{StaticResource White}"/>
    <SolidColorBrush x:Key="BlackBrush" Color="{StaticResource Black}"/>
    <SolidColorBrush x:Key="Gray100Brush" Color="{StaticResource Gray100}"/>
    <SolidColorBrush x:Key="Gray200Brush" Color="{StaticResource Gray200}"/>
    <SolidColorBrush x:Key="Gray300Brush" Color="{StaticResource Gray300}"/>
    <SolidColorBrush x:Key="Gray400Brush" Color="{StaticResource Gray400}"/>
    <SolidColorBrush x:Key="Gray500Brush" Color="{StaticResource Gray500}"/>
    <SolidColorBrush x:Key="Gray600Brush" Color="{StaticResource Gray600}"/>
    <SolidColorBrush x:Key="Gray900Brush" Color="{StaticResource Gray900}"/>
    <SolidColorBrush x:Key="Gray950Brush" Color="{StaticResource Gray950}"/>

    <Color x:Key="Yellow100Accent">#F7B548</Color>
    <Color x:Key="Yellow200Accent">#FFD590</Color>
    <Color x:Key="Yellow300Accent">#FFE5B9</Color>
    <Color x:Key="Cyan100Accent">#28C2D1</Color>
    <Color x:Key="Cyan200Accent">#7BDDEF</Color>
    <Color x:Key="Cyan300Accent">#C3F2F4</Color>
    <Color x:Key="Blue100Accent">#3E8EED</Color>
    <Color x:Key="Blue200Accent">#72ACF1</Color>
    <Color x:Key="Blue300Accent">#A7CBF6</Color>
</ResourceDictionary>

```

これらのファイル内の詳しい説明は省きますが、
app.xaml内でこの二つのファイルがResourceDictionaryに追加されています。

```xml
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:PIYOT"
             x:Class="PIYOT.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
```

各CotentsPageのxaml上でColors.xamlに定義されている色を使う場合、
```xml
    <Label BackgroundColor="{StaticResource Yellow100Accent}">
        ・・・
    </Label>
```
というように書けばOK。

コード側ではどうかと言うと、
```cs
    Color bgColor = Application.Current.Resources["Yellow100Accent"] as Color;
    // ※ResourceDictionaryに指定されたキーがなく、エラーになります。
```
では、取得できませんでした（汗）。

Application.Current.Resourcesの中には、
App.xaml内のResourceDictionary.MergedDictionariesタグで結合されたものは
どうやら含まれないようです。

どこにあるかと言うと、
Application.Current.Resources.MergedDictionaries内にあります。
デバッガーで確認したところ、xaml上で追加した順に格納されていました。

なので、コード上でColors.xamlの定義（ここではキー名：Yellow100Accent）を取得するには、
```cs
    ResourceDictionary targetResource = Application.Current.Resources.MergedDictionaries.ElementAt(0);
    Color bgColor = (Color)targetResource["Yellow100Accent"];
```
とすればよさそうです。
ちょっとスマートじゃないやり方ですが・・・（汗）。
実は自分が知らないだけで、もっと簡単に取得できるのかもですが、
とりあえずこれで取得できたので、追加の調査は今後ということで。

同じように悩んだ方がいたようで、
サイトStackOverflowにはResourceDictionaryを上書きしてしまう方法が
紹介されていました。
[https://stackoverflow.com/questions/72591153/how-to-find-a-resource-with-key-in-code-behind-maui](https://stackoverflow.com/questions/72591153/how-to-find-a-resource-with-key-in-code-behind-maui)

ご参考までに。