WPF: Reapply DataTemplateSelector when a certain value changes WPF: Reapply DataTemplateSelector when a certain value changes wpf wpf

WPF: Reapply DataTemplateSelector when a certain value changes


Regarding your EDIT, wouldn't a DataTemplate Trigger be enough instead of using a Style? That is:

<ItemsControl ItemsSource="{Binding Path=Groups}">    <ItemsControl.ItemTemplate>        <DataTemplate>            <ContentControl x:Name="cc" Content="{Binding}" ContentTemplate="{DynamicResource ItemTemplate}"/>            <DataTemplate.Triggers>                <DataTrigger Binding="{Binding Path=IsLeaf}" Value="False">                    <Setter TargetName="cc" Property="ContentTemplate" Value="{DynamicResource GroupTemplate}"/>                </DataTrigger>            </DataTemplate.Triggers>                                    </DataTemplate>    </ItemsControl.ItemTemplate></ItemsControl>


I found this workaround that seems easier to me. From within the TemplateSelector listen to the property that your care about and then reapply the template selector to force a refresh.

public class DataSourceTemplateSelector : DataTemplateSelector{    public DataTemplate IA { get; set; }    public DataTemplate Dispatcher { get; set; }    public DataTemplate Sql { get; set; }    public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)    {        var ds = item as DataLocationViewModel;        if (ds == null)        {            return base.SelectTemplate(item, container);        }        PropertyChangedEventHandler lambda = null;        lambda = (o, args) =>            {                if (args.PropertyName == "SelectedDataSourceType")                {                    ds.PropertyChanged -= lambda;                    var cp = (ContentPresenter)container;                    cp.ContentTemplateSelector = null;                    cp.ContentTemplateSelector = this;                                        }            };        ds.PropertyChanged += lambda;        switch (ds.SelectedDataSourceType.Value)        {            case DataSourceType.Dispatcher:                return Dispatcher;            case DataSourceType.IA:                return IA;            case DataSourceType.Sql:                return Sql;            default:                throw new NotImplementedException(ds.SelectedDataSourceType.Value.ToString());        }    }}


Returning back to your original solution and the problem of "the template selector doesn't get reapplied": you can refresh your view like that

CollectionViewSource.GetDefaultView(YourItemsControl.ItemsSource).Refresh();

where for brevity sake your ItemsControl is referenced by its name ("YourItemsControl") added to your XAML:

<ItemsControl x:Name="YourItemsControl" ItemsSource="{Binding Path=Groups}" ItemTemplateSelector="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=ListTemplateSelector}"/>

The only problem may be how to choose right place in your project for this refresh instruction. It could go into a view code-behind, or, if your IsLeaf is a DP, the right place would be a dependency-property-changed callback.