我正在尝试基于datatrigger切换contentpresenter的内容.我想在contentpresenter.content中显示usercontrol,如果我有值集,或者我需要显示错误消息.但是我的datatrigger上的绑定失败声明找不到该属性.我无法获取datacontext继承数据触发器检查.我可以通过使用注释掉的代码使其工作.但我很困惑为什么它不能正常工作.
<ContentPresenter.Style>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Content" Value="{Binding UC}"/>
<Style.Triggers>
<!--<DataTrigger Binding="{Binding DataContext.HasValue,RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}" Value="false">
<Setter Property="Content" Value="No preview"/>
</DataTrigger>-->
<DataTrigger Binding="{Binding HasValue}" Value="false">
<Setter Property="Content" Value="No value"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
Run Code Online (Sandbox Code Playgroud)
如果要使用触发器显示UserControl,则应使用ContentControl而不是ContentPresenter.我更喜欢使用ContentPresenter进行CustomControls,当我在系统中使用UserControl查看自定义数据类型时,以及允许给出动态行为.
示例:要切换ContentPresenter的模板,您需要像这样设置ContentTemplateSelector
<ContentPresenter Content="{Binding MyContent}"
ContentTemplate="{Binding MyContentTemplate}"
ContentTemplateSelector="{Binding MyContentTemplateSelector}"/>
Run Code Online (Sandbox Code Playgroud)
MyContent,MyContentTemplate和MyContentTemplateSelector是依赖项属性,无论您在何处使用其实例,都可以绑定.
阅读:
ContentControl和ContentPresenter有什么区别
问题中提到的绑定不起作用
ContentPresenter的DataContext自动设置为其Content属性的值,而ContentControl的DataContext则不是.
绑定是相对于DataContext属性的值解析的.如果在ContentPresenter上声明绑定,则在设置其内容的那一刻,将重新评估绑定.
可以根据您的要求在任何触发器上更改ContentControl.Content属性.如果要使用它来更改ViewModel属性的PropertyChanged事件,可以通过将DataTmplate与其中的UserControl实例或使用该UserControl的静态资源绑定到DataTemplate来使用它.
<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>
Run Code Online (Sandbox Code Playgroud)
阅读 如何使用内容模板触发,更多的细节在这里
DataTemplate和StaticResource范围的区别在于DataTemplate每次应用时都会创建模板的新实例.而StaticResource再次使用相同的UserControl实例(静态实例).您还可以使用EventTriggers更改内容基础don控制事件,如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>
Run Code Online (Sandbox Code Playgroud)
...然后:
<ContentControl Content="{Binding Solution}" />
Run Code Online (Sandbox Code Playgroud)
Ank*_*esh -2
我通常使用这样的触发器...
<UserControl>
<UserControl.Resources>
<DataTemplate x:Key="normalTemplate" >
<!-Fav UserControl->
</DataTemplate >
<DataTemplate x:Key="overWriteTempalte">
<!-Fav UserControl-> </DataTemplate>
</UserControl.Resources>
<ContentPresenter x:Name="ContentField"
Content="{Binding}"
ContentTemplate="{StaticResource ResourceKey=normalTemplate}" />
<UserControl.Triggers>
<DataTrigger Binding="{Binding Path=MyProperty}" Value="True">
<Setter TargetName="ContentField" Property="ContentTemplate" Value="{StaticResource ResourceKey=overWriteTempalte}" />
</DataTrigger>
</UserControl.Triggers>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
如果绑定有问题 使用 Snoop 检测绑定错误