无法从样式的datatrigger更改ContentControl的模板 - datatrigger未触发

时间:2014-05-19 06:07:52

标签: wpf xaml mvvm

Hello WPF aficionados,

我在用户控件中有一个内容控件,它将数据上下文设置为同一usercontrol中列表视图的选定项。视图模型上的选定项属性称为选择

以下是内容控制的声明:

<ContentControl DataContext="{Binding Selection}">
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Setter Property="Template"  Value="{StaticResource JobSnapShotProgDetail}"/>                            
            <Style.Triggers>
                <DataTrigger Binding="{Binding bTandM}" Value="1">
                    <Setter Property="Template" Value="{StaticResource JobSnapShotProgDetail}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding bTandM}" Value="0">
                    <Setter Property="Template" Value="{StaticResource JobSnapShotTM_Detail}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>                        
    </ContentControl.Style>
</ContentControl> 

模板在另一个资源文件中定义为ControlTemplates,如:

 <ControlTemplate x:Key="JobSnapShotProgDetail" >
     ...
 </ControlTemplate >
 <ControlTemplate x:Key="JobSnapShotTM_Detail" >
     ...
 </ControlTemplate >

绑定非常有意义,模板的字段都显示来自Selection对象的正确数据。

我的问题:

我希望内容控件根据Selection的bTandM属性的值使用两个不同控件模板中的一个。

现在发生了什么:

当我更改列表视图的选择,这会更改选择对象时,模板不会根据选择 bTandM的值进行更改property(sql server位数据类型)。是的选择对象实现了iNotifyPropertyChanged,并且绑定到选择属性的ControlTemplate字段都显示正确的数据而没有任何绑定错误输出窗口。

我尝试了什么:

似乎数据触发器没有得到&#34; HIT&#34;通过代码。我试图通过添加foo而不是应该无法转换的数字来中断数据触发器,但不会生成错误。即:

 <DataTrigger Binding="{Binding bTandM}" Value="foo">

这让我相信触发器由于某种原因没有触发。

问题:

有人可以帮我弄清楚为什么这个数据触发无效。

提前致谢

JK


编辑1:

我尝试使用HERE找到的技术,但它也不起作用。数据触发器不会被解雇。

将DataTemplate与DataTriggers一起使用的新尝试以Datacontrol的模板属性为目标:

<ItemsControl ItemsSource="{Binding SelectionCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentControl x:Name="DetailControl" Template="{DynamicResource JobSnapShotProgDetail}" />
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding bTandM}" Value="False">
                    <Setter TargetName="DetailControl" Property="Template" Value="{DynamicResource JobSnapShotProgDetail}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding bTandM}" Value="1">
                    <Setter TargetName="DetailControl" Property="Template" Value="{DynamicResource JobSnapShotTM_Detail}" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

同样,模板加载正常,并且样式设置器中的初始模板集正确显示属性,但模板不会根据对象的bTandM布尔属性进行更改。

2 个答案:

答案 0 :(得分:3)

好的,所以这是NotifyPropertyChanged的一个问题。

我的viewmodel 的选择属性实现INPC,但问题是底层类类型 vw_Job_Snapshot ,它是来自sql server视图的映射实体选择的没有。

我必须在底层类中实现iNPC,然后在我的viewmodel中使用Selection Property的Property Setter来同时通知特定的bTandM属性更改:

    Public Property Selection As vw_Job_Snapshot
        Get
            Return Me._Selection
        End Get
        Set(ByVal value As vw_Job_Snapshot)
            Me._Selection = value

            ''Notify of specific property changed
            value.OnPropertyChanged("bTandM")

            _Selection = value
            RaisePropertyChanged(JobSnapshotSelectedPropertyName)
        End Set
    End Property

在此之后,我视图中的以下代码完美运行:

<ContentControl DataContext="{Binding Selection}">
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Setter Property="Template"  Value="{DynamicResource JobSnapShotTM_Detail}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding bTandM}" Value="False">
                    <Setter Property="Template" Value="{DynamicResource JobSnapShotProgDetail}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding bTandM}" Value="True">
                    <Setter Property="Template" Value="{DynamicResource JobSnapShotTM_Detail}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

感谢所有帮助过的人

答案 1 :(得分:1)

请尝试使用DataTemplateSelector

您的选择器看起来像这样(我假设您的类名为JobSnapShot):

public class JobSnapShotDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null && item is JobSnapShot)
        {
            JobSnapShot jobSnapShot = item as JobSnapShot;

            if (jobSnapShot.bTandM == 1)
                return
                    element.FindResource("JobSnapShotProgDetail") as DataTemplate;
            else
                return
                    element.FindResource("JobSnapShotTM_Detail") as DataTemplate;
        }

        return null;
    }
}

XAML:

<Window.Resources>
    <local:JobSnapShotDataTemplateSelector x:Key="myDataTemplateSelector"/>
</Window.Resources>



<ContentControl ItemTemplateSelector="{StaticResource myDataTemplateSelector}" .... />