nakamurakko’s blog

仕事で覚えたこと、勉強したことを自分のメモ代わりに書いていこうかなと。

DocumentCompositeNodeにキャストできません

実行環境:Visual Studio 2017 Professional

困った事象

WPFで、Styleなどを定義した外部ResourceDictionaryをExpander.HeaderTemplate内に適用したくて、次のように書いた。

<Window x:Class="WpfDataTemplateStyleNG.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:WpfDataTemplateStyleNG"
        mc:Ignorable="d"
        Title="WpfDataTemplateStyleNG"
        Height="200"
        Width="300">

    <StackPanel>
        <Expander>
            <Expander.HeaderTemplate>
                <DataTemplate>
                    <DataTemplate.Resources>
                        <!--DataTemplateで外部リソースを設定。-->
                        <ResourceDictionary Source="Styles.xaml" />
                    </DataTemplate.Resources>

                    <TextBlock Text="Expander.HeaderTemplate上のTextBlock" />
                </DataTemplate>
            </Expander.HeaderTemplate>

        </Expander>

        <TextBlock Text="StackPanel上のTextBlock" />
    </StackPanel>

</Window>

コードは問題なさそうだけど、こんなエラーが出た。(ただ、エラーにはなるけど、ビルドは正常に完了するし、実行も問題なくできる。)

'OnDemandResourceDictionary' のオブジェクトを型 'Microsoft.VisualStudio.DesignTools.Markup.DocumentModel.DocumentCompositeNode' にキャストできません。

調べてみると、Microsoftに報告されていて、対応しないことになっている。

XAML designer broken when adding resource dictionaries to data or control templates


回避策

エラーになるのは困るので、回避策としては、

  • StaticResourceを使う。
  • Template内で使用する前にカスタムコントロール化して、カスタムコントロールの方で外部リソースを読み込む。

という感じですかね。

ちなみに、上記Expanderの場合は次のようにHeaderTemplateではなく、Headerに直接書けば回避できた。

<Window x:Class="WpfDataTemplateStyle.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:WpfDataTemplateStyle"
        mc:Ignorable="d"
        Title="WpfDataTemplateStyle"
        Height="200"
        Width="300"
        FontSize="15">

    <StackPanel>
        <Expander>
            <Expander.Header>
                <HeaderedContentControl>
                    <HeaderedContentControl.Resources>
                        <!--これはエラーにならない。-->
                        <ResourceDictionary Source="Styles.xaml" />
                    </HeaderedContentControl.Resources>

                    <TextBlock Text="Expander.HeaderTemplate上のTextBlock" />
                </HeaderedContentControl>
            </Expander.Header>

        </Expander>

        <TextBlock Text="StackPanel上のTextBlock" />
    </StackPanel>

</Window>

ControlTemplate、DataTemplateで外部リソースを書いてもエラーにならない場合があるけど、条件は分からない。