実行環境: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で外部リソースを書いてもエラーにならない場合があるけど、条件は分からない。