1
votes

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: Hard typed XAML view with nested virtual groups

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

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?

1

1 Answers

2
votes

I posted the same question on an MSDN forum and got this answer from a guy in Microsoft: http://social.msdn.microsoft.com/Forums/en-US/e9d82eb7-86e4-4d06-b35e-f555b97efe74/winrt-listview-with-two-level-grouping?forum=winappswithcsharp

So, I just modified the sample to be dynamic regarding categories for each version, which fitted my ViewModel perfectly. It was much easier to accomplish what I needed when not trying to use the CollectionViewSource grouping that most samples are about.

This is my final XAML code:

<ListView ItemsSource="{Binding Versions}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Margin="0,10,0,5" Style="{StaticResource SubheaderTextBlockStyle}" Foreground="{ThemeResource AccentColorBrush}">
                            <Run Text="{Binding VersionString}" /><Run Text=" (" /><Run Text="{Binding ReleaseDateString}" /><Run Text=")" />
                </TextBlock>
                <ListView ItemsSource="{Binding Categories}">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock Margin="0,5,0,2" Style="{StaticResource SubheaderTextBlockStyle}" Text="{Binding Category}" />
                                <ListView ItemsSource="{Binding Items}">
                                    <ListView.ItemTemplate>
                                        <DataTemplate>
                                            <StackPanel>
                                                <TextBlock Margin="5,2,0,0" Style="{StaticResource BodyTextBlockStyle}" LineStackingStrategy="MaxHeight">
                                                    <Run>-</Run><Run Text="{Binding Text}" />
                                                </TextBlock>
                                            </StackPanel>
                                        </DataTemplate>
                                    </ListView.ItemTemplate>
                                </ListView>
                            </StackPanel>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

And the result looks like this:

Screenshot