简体   繁体   中英

UWP: DataTemplateSelector and SelectedItem

How can I change the DataTemplate for the SelectedItem of ListView in UWP project? I'm trying to use the DataTemplateSelector but the problem is that SelectTemplateCore is called only one time.

This what I have tried:

MyTemplateSelector class

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate SelectedItemTemplate { get; set; }
    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        var cont = container as ListViewItem;
        if (cont != null)
        {
            FrameworkElement elemnt = container as FrameworkElement;
            if (cont.IsSelected)
            {
                return SelectedItemTemplate;
            }
            else
            {
                return DefaultTemplate;
            }
        }
        else
            return DefaultTemplate;
    }
}

Resources of the page

<Page.Resources>
    <DataTemplate x:Key="DefaultTemplate">
        <Grid Height="44">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="44" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <SymbolIcon Grid.Column="0" Symbol="{Binding Icon, Mode=OneWay}" Foreground="Black"
                        Height="40" Width="40" Margin="2"/>
            <TextBlock Grid.Column="1" Text="{Binding Name, Mode=OneWay}" FontSize="16" VerticalAlignment="Center" Foreground="Black" />
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="SelectedItemTemplate">
        <Grid Height="44" Background="Black">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="44" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <SymbolIcon Grid.Column="0" Symbol="{Binding Icon, Mode=OneWay}" Foreground="Black"
                        Height="40" Width="40" Margin="2"/>
            <TextBlock Grid.Column="1" Text="{Binding Name, Mode=OneWay}" FontSize="16" VerticalAlignment="Center" Foreground="Black" />
        </Grid>
    </DataTemplate>
    <local:DefaultTemplateSelector x:Key="TemplateSelector"
                                   DefaultTemplate="{StaticResource DefaultTemplate}"
                                   SelectedItemTemplate="{StaticResource SelectedItemTemplate}"/>
</Page.Resources>

ListView

<ListView x:Name="MyListView" ItemContainerStyle="{StaticResource DefaultStyle}" ItemTemplateSelector="{StaticResource TemplateSelector}">
</ListView>

One way is to use RegisterPropertyChangedCallback to monitor the changes of the IsSelected property and then update the ContentTemplateSelector of the ListViewItem manually -

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
    if (container is ListViewItem cont)
    {
        if (cont.Tag != null && long.TryParse(cont.Tag.ToString(), out var token))
        {
            cont.UnregisterPropertyChangedCallback(ListViewItem.IsSelectedProperty, token);
        }

        cont.Tag = cont.RegisterPropertyChangedCallback(ListViewItem.IsSelectedProperty, (s, e) =>
        {
            cont.ContentTemplateSelector = null;
            cont.ContentTemplateSelector = this;
        });

        if (cont.IsSelected)
        {
            return SelectedItemTemplate;
        }

        return DefaultTemplate;
    }

    return DefaultTemplate;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM