Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping GridView in Windows 8 Metro App

Can someone give me some hints how to accomplish the grouping within a GridView for Metro Apps as shown in the Screenshot below.

zoomed out image

This Screenshot is from the Developer Resources for Windows Metro Apps, but unfortunately there is no description how to accomplish it.

I have the following code snippet:

Xaml:

    ...

    <Page.Resources>
        <CollectionViewSource x:Name="cvs" IsSourceGrouped="true"/>
    </Page.Resources>

    <Grid Background="{StaticResource DefaultBackground}">

        <GridView x:Name="DefaultGridView" ItemsSource="{Binding Source={StaticResource cvs}}">
            <GridView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Fill="{Binding}" Width="100" Height="100" Margin="0 0 5 0"/>
                    </StackPanel>
                </DataTemplate>
            </GridView.ItemTemplate>

            <GridView.GroupStyle>
                <GroupStyle>

                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock Text='{Binding Key}' Foreground="Gray" Margin="5" FontSize="30" FontFamily="Segoe UI Light" />
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>

                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <VariableSizedWrapGrid MaximumRowsOrColumns="2" Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>

                </GroupStyle>
            </GridView.GroupStyle>


            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                   <StackPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>


        </GridView>

    </Grid>

...

C#:

In the Code-Behind I do the following in the OnNavigateTo Method:

        List<string> strList = new List<string>() { 
        "Red", "Red", "Red", "Red", "Red", "Red", 
        "Green", "Green","Green","Green","Green",
        "Blue","Blue","Blue","Blue" };

    var groupedList = from s in strList
                      group s by s into g
                      orderby g.Key
                      select g;


    cvs.Source = groupedList;

No matter what I do, I am not able to group the Items in a continues list like in the Screenshot. The Code results in separate lists grouped side by side.

like image 328
Edmond Simbari Avatar asked Mar 25 '12 16:03

Edmond Simbari


2 Answers

I may have a solution. In my projet, I had to create a list of contacts in alphabetic order, like the People app.

I used a GridView (with this sample), a CollectionViewSource and a wrappanel I found in the WinRT XAML Toolkit (you can get with NuGet package or copy/paste the source code). It allow you to put your items in columns.

Example

enter image description here

ViewModel

class ContactListViewModel
    {

        public ContactListViewModel()
        {
            ContactSource = new CollectionViewSource();
            Contacts = new ObservableCollection<Contact>();

            Contacts.Add(new Contact("Gates","Bill"));
            Contacts.Add(new Contact("Bush","Georges"));
            Contacts.Add(new Contact("Obama","Barack"));
            Contacts.Add(new Contact("Hollande","François"));
            Contacts.Add(new Contact("Affleck","Ben"));
            Contacts.Add(new Contact("Allen","Woody"));
            Contacts.Add(new Contact("Hendrix","Jimi"));
            Contacts.Add(new Contact("Harrison", "Georges"));

            Contacts = new ObservableCollection<Contact>(Contacts.OrderBy(c => c.Name));
            ContactSource.Source = GetGroupsByLetter();
            ContactSource.IsSourceGrouped = true;

        }

        #region Contacts
        public ObservableCollection<Contact> Contacts
        {
            get;
            protected set;
        }

        public CollectionViewSource ContactSource
        {
            get;
            protected set;
        }
        #endregion


        internal List<GroupInfoList<object>> GetGroupsByLetter()
        {
            List<GroupInfoList<object>> groups = new List<GroupInfoList<object>>();

            var query = from item in Contacts
                        orderby ((Contact)item).Name
                        group item by ((Contact)item).Name[0] into g
                        select new { GroupName = g.Key, Items = g };
            foreach (var g in query)
            {
                GroupInfoList<object> info = new GroupInfoList<object>();
                info.Key = g.GroupName;
                foreach (var item in g.Items)
                {
                    info.Add(item);
                }
                groups.Add(info);
            }

            return groups;
        }

        public class GroupInfoList<T> : List<object>
        {

            public object Key { get; set; }


            public new IEnumerator<object> GetEnumerator()
            {
                return (System.Collections.Generic.IEnumerator<object>)base.GetEnumerator();
            }
        }
}

View

 <DataTemplate x:Key="contactTemplate">
    <Grid Width="225" Height="75" Background="#55FFFFFF">
        <Grid Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="20">
                <Run Text="{Binding FirstName}"/>
                <Run Text="{Binding Name}"/>
            </TextBlock>
            <TextBlock Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding Email}" FontSize="13" Foreground="#FFDDDDDD"/>
        </Grid>
    </Grid>
</DataTemplate>

<DataTemplate x:Key="letterTemplate">
    <Grid Margin="5,0,0,5" Width="225">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding Key}" Style="{StaticResource GroupHeaderTextStyle}"  VerticalAlignment="Center"/>
        <Rectangle Grid.Row="1" Fill="#BBEEEEEE" Height="1" Margin="0,7,0,0"/>
    </Grid>
</DataTemplate>
</Page.Resources>



<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid Style="{StaticResource LayoutRootStyle}">
    <Grid.RowDefinitions>
        <RowDefinition Height="140"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!-- Back button and page title -->
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Button x:Name="backButton" Click="GoBack" Style="{StaticResource BackButtonStyle}" Opacity="0"/>
        <TextBlock x:Name="pageTitle" Grid.Column="1" Text="Manager" Style="{StaticResource PageHeaderTextStyle}"/>
    </Grid>

    <GridView Grid.Row="1"
        ItemsSource="{Binding Path=ContactSource.View}"
        SelectionMode="Multiple"
        IsSwipeEnabled="false"
        IsItemClickEnabled="True"
        Padding="116,10,40,46"
        ItemTemplate="{StaticResource contactTemplate}">

        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <local:WrapPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>

        <GridView.GroupStyle>
            <GroupStyle HeaderTemplate="{StaticResource letterTemplate}">
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </GridView.GroupStyle>
    </GridView>
</Grid>
like image 148
Max Avatar answered Sep 26 '22 19:09

Max


http://code.msdn.microsoft.com/windowsapps/GroupedGridView-77c59e8e

like image 24
Xyroid Avatar answered Sep 23 '22 19:09

Xyroid