Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

c# - WPF: Reapply DataTemplateSelector when a certain value changes

So here is the XAML that I have:

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

Here is my ListTemplateSelector class:

public class ListTemplateSelector : DataTemplateSelector {
public DataTemplate GroupTemplate { get; set; }
public DataTemplate ItemTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container) {
    GroupList<Person> list = item as GroupList<Person>;
    if (list != null && !list.IsLeaf)
        return GroupTemplate;
    return ItemTemplate;
}
}

The GroupTemplate data template references the ListTemplateSelector inside itself, so this is why I have set up like I have it set up. It's the only recursive hack I could put together. But that's not the problem I'm having.

My problem is, I want to change from ItemTemplate to GroupTemplate when the IsLeaf property changes. This works beautifully the very first time since it reads the property the first time. But once this property changes, the template selector doesn't get reapplied. Now, I could use triggers to bind to the value and set the item template appropriately, but I need to be able to set a different template for each item, as they could be in a different state.

For instance, say I have a list of groups like this:

Group 1: IsLeaf = false, so template = GroupTemplate

Group 2: IsLeaf = true, so template = ItemTemplate

Group 3: IsLeaf = false, so template = GroupTemplate

And once group 1's IsLeaf property changes to true, the template needs to automatically change to ItemTemplate.

EDIT:

Here is my temporary solution. Any better way to do it?

<ItemsControl ItemsSource="{Binding Path=Groups}">
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <ContentControl Content="{Binding}">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{DynamicResource ItemTemplate}"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsLeaf}" Value="False">
                            <Setter Property="ContentTemplate" Value="{DynamicResource GroupTemplate}"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...