DataTrigger を既存の要素に動的に追加するときに問題が発生します。
このように MainWindow.XAML でハードコーディングすると、正常に動作します。
App.Xaml で:
...
<Application.Resources>
<ControlTemplate x:Key="MyTemplate">
<TextBox AcceptsReturn="True" AcceptsTab="True" AllowDrop="True" Text="{Binding Content}"/>
</ControlTemplate>
</Application.Resources>
...
MainWindow.XAML で:
...
<DataTemplate>
<Control x:Name="ViewPlaceHolder" Template="{StaticResource ViewPlaceHolderTemplate}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding TypeName}" Value="MyViewModelName">
<Setter TargetName="ViewPlaceHolder" Property="Template" Value="{StaticResource MyTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
...
しかし、次のように分離コードで DataTrigger を作成すると:
...
DataTrigger tr = new DataTrigger();
Binding b = new Binding();
b.Path = new PropertyPath("TypeName");
tr.Value = triggerValue;
tr.Binding = b;
Setter st = new Setter(Control.TemplateProperty, "{StaticResource MyTemplate}");
st.TargetName = "ViewPlaceHolder";
tr.Setters.Add(st);
myDataTemplate.Triggers.Add(tr);
...
バインド中に次のエラーが発生します (トリガーをテンプレートに追加してもエラーは発生せず、XamlWriter.Write(myDataTemplate) を使用すると DataTemplate に適切に追加されたことが示されます):
'StaticResource MyTemplate' は、Setter の 'System.Windows.Controls.Control.Template' プロパティの有効な値ではありません。
(triggerValue) は動的にロードされたプラグインから取得されるため、実行時にトリガーをロードする必要があります。ControlTemplate を StaticResource として参照するのではなく、Setter に直接追加しても問題なく動作しますが、必要なすべてのページ/ウィンドウに同じ ControlTemplate をロードする必要があるという考えは好きではありません。
コードビハインドからリソースを追加した場合、DataTrigger の Setter を取得してリソースを参照する方法について何か考えはありますか?