contentpresenter.content上的Datatrigger无法正常工作

bij*_*iju 4 wpf datatrigger

我正在尝试基于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)

Aka*_*aur 6

如果要使用触发器显示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是依赖项属性,无论您在何处使用其实例,都可以绑定.

阅读:

ContentPresenter的用法

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 检测绑定错误