如果你想使用触发器来显示 UserControl,你应该使用 ContentControl 而不是 ContentPresenter。
我更喜欢将 ContentPresenter 用于 CustomControls,当我使用 UserControl 来查看系统中的自定义数据类型并允许提供动态行为时。
示例:要为 ContentPresenter 切换模板,您需要像这样设置 ContentTemplateSelector
<ContentPresenter Content="{Binding MyContent}"
ContentTemplate="{Binding MyContentTemplate}"
ContentTemplateSelector="{Binding MyContentTemplateSelector}"/>
MyContent、MyContentTemplate 和 MyContentTemplateSelector 是依赖属性,可以在任何使用它的实例的地方绑定。
阅读:
Usage of ContentPresenter
What is the difference between ContentControl and ContentPresenter
问题中提到的绑定不起作用
ContentPresenter 的 DataContext 自动设置为
它的 Content 属性,而 ContentControl 的 DataContext 不是。
绑定相对于 DataContext 属性的值进行解析。如果您在 ContentPresenter 上声明绑定,则在设置其内容的那一刻,绑定将被重新评估。
ContentControl.Content 属性可以根据您的要求在任何触发器上更改。如果您想使用它来更改 ViewModel 的属性的 PropertyChanged 事件,可以通过将 DataTrigger 与其中带有 UserControl 实例的 DataTemplate 绑定或使用该 UserControl 的静态资源来使用 DataTrigger。
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Value="{StaticResource UnSelectedDataTemplate}" Property="ContentTemplate" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
<Setter Value="{StaticResource SelectedDataTemplate}" Property="ContentTemplate" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentContro.Style>
</ContentControl>
阅读How to use triggers for content template,更多详情here
DataTemplate 和 StaticResource 范围的区别在于,DataTemplate 每次应用模板时都会创建一个新的模板实例。
然而,StaticResource 再次使用 UserControl 的相同实例(静态实例)。
您还可以使用 EventTriggers 来更改内容库,例如 MouseOver 等控制事件。
替代方法
与上述非常相似,略有不同。在资源中定义为数据模板。内容更改的触发本质上是相同的。
...在<x.Resources /> 标签中:
<DataTemplate x:Key="DesignerTemplate" DataType="{x:Type vm:SolutionViewModel}">
<vw:SolutionDesignerView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SolutionViewModel}">
<ContentControl Content="{Binding }">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoaded}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource DesignerTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
...然后:
<ContentControl Content="{Binding Solution}" />