locked
WinRT ListView with two level grouping

    Question

  • I'm trying to do nested grouping on two levels using the WinRT ListView component. So far I haven't been able to transfer the samples I've found for WPF, because the WinRT components lack a few of the properties that exists in WPF - for instance the CollectionViewSource in WinRT doesn't have the GroupDescriptions property used to define several groups.

    The view I'm trying to make is like this:

    So far I've been able to get a view like this in WinRT - the version level is missing:

    The XAML I've come up with so far has two CollectionViewSource objects where I set the Source of the categoryViewSource equal to the View of the versionViewSource. The ListView's ItemsSource is bound to the categoryViewSource. This obviously works at some extent, as I'm getting some data displayed.

    <UserControl.Resources>
        <DataTemplate x:Key="versionTemplate">
            <TextBlock Margin="10" Style="{StaticResource SubheaderTextBlockStyle}" Foreground="{ThemeResource AccentColorBrush}">
                                <Run Text="{Binding VersionString}" /><Run Text=" (" /><Run Text="{Binding ReleaseDateString}" /><Run Text=")" />
            </TextBlock>
        </DataTemplate>
        <DataTemplate x:Key="categoryTemplate">
            <TextBlock Margin="10" Style="{StaticResource SubheaderTextBlockStyle}" Foreground="{ThemeResource AccentColorBrush}" Text="{Binding Category}" />
        </DataTemplate>
        <DataTemplate x:Key="releaseNoteTemplate">
            <TextBlock Margin="10" Style="{StaticResource BodyTextBlockStyle}" Text="{Binding Text}" />
        </DataTemplate>
        <local:ReleaseNotesTemplateSelector x:Key="releaseNotesTemplateSelector"
                                              VersionTemplate="{StaticResource versionTemplate}"
                                              CategoryTemplate="{StaticResource categoryTemplate}"/>
        <CollectionViewSource x:Name="versionViewSource" IsSourceGrouped="True" ItemsPath="Categories" />
        <CollectionViewSource x:Name="categoryViewSource" IsSourceGrouped="True" ItemsPath="Items" />
    </UserControl.Resources>
    
    <ListView ItemsSource="{Binding Source={StaticResource categoryViewSource}}" 
              ItemTemplate="{StaticResource releaseNoteTemplate}"
              IsItemClickEnabled="False">
        <ListView.GroupStyle>
            <GroupStyle HeaderTemplateSelector="{StaticResource releaseNotesTemplateSelector}" />
        </ListView.GroupStyle>
    </ListView>

    The Source properties are set in code behind like this:

    if (this.DataContext is ReleaseNotesViewModel)
    {
        this.versionViewSource.Source = this.ViewModel.Versions;
        this.categoryViewSource.Source = this.versionViewSource.View;
    }

    The ReleaseNotesTemplateSelector works like this:

    public class ReleaseNotesTemplateSelector : DataTemplateSelector
    {
        public DataTemplate VersionTemplate { get; set; }
        public DataTemplate CategoryTemplate { get; set; }
    
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            if (item is ReleaseNoteVersionViewModel)
                return this.VersionTemplate;
            else if (item is ReleaseNoteCategoryViewModel)
                return this.CategoryTemplate;
    
            return base.SelectTemplateCore(item, container);
        }
    }
    I could of course continue using a hard typed view, but I would rather have a dynamically generated view if possible. Does anyone have a suggestion on how I can get nested grouping to display version number in the first group level?

    eloekset

    Tuesday, July 15, 2014 5:13 PM

Answers

  • I used nested ListViews to achieve this objective:

      <Grid>
            <ListView x:Name="MyListView" Margin="30">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding Description}" Foreground="Yellow" FontSize="40"/>
                            <TextBlock Text="Changes" FontSize="30"/>
                            <ListView ItemsSource="{Binding Changes}">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="   - " FontSize="21"/>
                                            <TextBlock Text="{Binding}" FontSize="21"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                            <TextBlock Text="Known issues" FontSize="30"/>
                            <ListView ItemsSource="{Binding KnownIssues}" >
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="   - " FontSize="21"/>
                                            <TextBlock Text="{Binding}" FontSize="21"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                            <TextBlock Text="Plans for next release" FontSize="30"/>
                            <ListView ItemsSource="{Binding Plans}">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="   - " FontSize="21"/>
                                            <TextBlock Text="{Binding}" FontSize="21"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
                        </StackPanel>
                    </DataTemplate>    
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
       protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                List<Version> Versions = new List<Version>();
                Version V1 = new Version();
                Version V2 = new Version();
                Versions.Add(V1);
                Versions.Add(V2);
    
                V1.Description = "Version 1.1 (12/19/2011)";
                V1.Changes.Add("Error reporting by email.");
                V1.Changes.Add("Game settings to adjust game speed.");
                V1.KnownIssues.Add("Player action not visible after starting a new game.");
                V1.KnownIssues.Add("If a player finished with a 6 on the die, the turn is not passed to the next player.");
                V1.Plans.Add("Support landscape mode.");
                V1.Plans.Add("Support online multiplayer games.");
    
                V2.Description = "Version 1.0 (12/02/2011)";
                V2.Changes.Add("V1.0 Change1");
                V2.Changes.Add("V1.0 Change2");
                V2.KnownIssues.Add("V1.0 KnownIssues1");
                V2.KnownIssues.Add("V1.0 KnownIssues2");
                V2.Plans.Add("V1.0 Plans1");
                V2.Plans.Add("V1.0 Plans2");
    
                MyListView.ItemsSource = Versions;
            }
        }
    }
    
    
    public class Version
    {
        public string Description { get; set; }
        public List<string> Changes { get; set; }
        public List<string> KnownIssues { get; set; }
        public List<string> Plans { get; set; }
    
        public Version ()
        {
            Changes = new List<string>();
            KnownIssues = new List<string>();
            Plans = new List<string>();
        }
    }



    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Tuesday, July 15, 2014 7:46 PM
    Moderator