ContentTemplateSelector is only called one time showing always the same datatemplate

拈花ヽ惹草 提交于 2019-11-30 13:58:49

I like Neil's solution (found on Josh's post via the link you provided):

<DataTemplate DataType="{x:Type local:MyType}">
        <ContentPresenter Content="{Binding}" Name="cp" />
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=IsRunning}" Value="True">
                <Setter TargetName="cp" Property="ContentTemplate" Value="{StaticResource StopTemplate}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsRunning}" Value="False">
                <Setter TargetName="cp" Property="ContentTemplate" Value="{StaticResource StartTemplate}" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

Edit: I couldn't actually get the above code to work, but this works using a style:


        <DataTrigger Binding="{Binding Path=SourceSystem.SourceSystemName}"
                     Value="mysite.com">
   <Setter Property="ContentControl.ContentTemplate" 
                    Value="{StaticResource mysiteToolbar}" />

        <DataTrigger Binding="{Binding Path=SourceSystem.SourceSystemName}"
                     Value="mysite2.com">
   <Setter Property="ContentControl.ContentTemplate" 
                    Value="{StaticResource mysiteToolbar2}" />

  </Style.Triggers>            

Note: I think this method is quite clumsy, but could work for some scenarios. I favor the method of using a trigger (from Neil) that I posted as a separate answer.


Another possible way is to bind the Content of the ContentTemplateSelector to the property that determines the template that should be selected. For instance here I have two different toolbars chosen based upon the value of SourceSystem. I set the Content to be the sourcesystem property itself.

<ContentControl ContentTemplateSelector="{StaticResource toolbarTemplateSelector}" 
                DataContext="{Binding}" Content="{Binding SourceSystem}" />

The template selector simply looks at the source system and returns the necessary template.

If the template needs access to the datacontext of the control, just use element binding to set it.

 <UserControl.Resources>
    <DataTemplate x:Key="toolbar1">
        <views:OrdersToolbar1View Margin="0,5,0,0" 
               DataContext="{Binding ElementName=control,Path=DataContext}"/>
    </DataTemplate>
    <DataTemplate x:Key="toolbar2">
        <views:OrdersToolbar2View Margin="0,5,0,0" 
               DataContext="{Binding ElementName=control,Path=DataContext}"/>
    </DataTemplate>
 </UserControl.Resources>

Use this method for custom Content Selector:

private void ReloadContent()
{
    MainContentControl.ContentTemplate = MainContentControl.ContentTemplateSelector.SelectTemplate(null, MainContentControl);
}

In xaml:

<ContentControl Content="{Binding}" x:Name="MainContentControl">
    <ContentControl.ContentTemplateSelector >
            <templateSelectors:MainViewContentControlTemplateSelector>
                <templateSelectors:MainViewContentControlTemplateSelector.BoysTemplate>
                    <DataTemplate>
                       <local:UserControl1 />
                    </DataTemplate>
                    </templateSelectors:MainViewContentControlTemplateSelector.BoysTemplate>
                <templateSelectors:MainViewContentControlTemplateSelector.GirlsTemplate>
                    <DataTemplate>
                        <local:UserControl2 />
                     </DataTemplate>
                     </templateSelectors:MainViewContentControlTemplateSelector.GirlsTemplate>
    </ContentControl>

And Selector :

public class MainViewContentControlTemplateSelector : DataTemplateSelector
{
    public DataTemplate BoysTemplate{ get; set; }
    public DataTemplate GirlsTemplate{ get; set; }


    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var contentControl = container.GetVisualParent<ContentControl>();
        if (contentControl == null)
        {
            return BoysTemplate;
        }

        if (//Condition)
        {
            return GirlsTemplate;

        }

        return BoysTemplate;
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!