سؤال

I want to group the GridViewItems in Alphabetical order, and show alphabet letter as Group Header.
I need

  • Header for GroupItems
  • Style for Group
  • Style for Item Panel
  • Template for GridViewItem

and explain how to add the grouped items to CollectionViewSource.

هل كانت مفيدة؟

المحلول

GridView Grouping can be done using CollectionViewSource. In your Xaml, add a CollectionViewSource in the Resources section of your page. Make sure IsSourceGrouped is set to true:

<Page.Resources>
    <CollectionViewSource x:Name="FruitsCollectionViewSource" IsSourceGrouped="True"/>
</Page.Resources>

We can set the Source of CollectionViewSource later from codebehind,

Then the CollectionViewSource(FruitsCollectionViewSource) should be set as the ItemsSource for your GridView

 <GridView
        ItemsSource="{Binding Source={StaticResource FruitsCollectionViewSource}}"
        x:Name="FruitGridView"
        Padding="30,20,40,0"
        SelectionMode="None"
        IsSwipeEnabled="false"
        IsItemClickEnabled="True"
        ItemClick="FruitGridView_ItemClick">

          //// GridView ItemTemplate

            <GridView.ItemTemplate>
                <DataTemplate>
                    <Grid HorizontalAlignment="Left" Width="250" Height="250">
                        <Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}">
                            <Image Source="{Binding Path=FruitImageSource}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
                        </Border>
                        <StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="Fruit Name" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="30" Margin="15,0,15,0"/>
                                <TextBlock Text="{Binding Path=FruitName}" Style="{StaticResource TitleTextBlockStyle}" Height="30" Margin="15,0,15,0"/>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="Fruit Rate" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,87,10"/>
                                <TextBlock Text="{Binding Path=FruitRate}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
                            </StackPanel>                          
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>

            ////Group Style

            <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>

             //// Item panel Style

            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsWrapGrid GroupPadding="0,0,70,0" />
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>                     
        </GridView>

Now you can add items to your FruitList from codebehind

Create an ObservableCollection FruitList

public ObservableCollection<Fruit> FruitList { get; set; }

create a model class Fruit

    public class Fruit
    {
        public string FruitName { get; set; }
        public string FruitImageSource { get; set; }
        public string FruitRate { get; set; }
    }

Initialize the FruitList and Add items to the FruitList

    FruitList.Add(new Fruit { FruitName = "Blackberry", FruitImageSource = "../Assets/blackberry.jpg", FruitRate = "150" });
    FruitList.Add(new Fruit { FruitName = "Apple", FruitImageSource = "../Assets/apple.jpg", FruitRate = "150" });
    FruitList.Add(new Fruit { FruitName = "Orange", FruitImageSource = "../Assets/orange.jpg", FruitRate = "250" });
    FruitList.Add(new Fruit { FruitName = "Bilberry", FruitImageSource = "../Assets/bilberry.jpg", FruitRate = "250" });
    FruitList.Add(new Fruit { FruitName = "Banana", FruitImageSource = "../Assets/banana.jpg", FruitRate = "50" });
    FruitList.Add(new Fruit { FruitName = "Amla", FruitImageSource = "../Assets/amla.jpg", FruitRate = "120" });

Now you can set the Source of you CollectionViewSource For that first we need to sort our FruitList. then group the fruit name by ascending or descending order using this GetGroupsByLetter() method.

        FruitList = new ObservableCollection<Fruit>(FruitList .OrderBy(c => c.FruitName));
        FruitsCollectionViewSource.Source = GetGroupsByLetter();

GetGroupsByLetter() groups the items in the FruitList.

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

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

            groups.Add(info);
        }

        return groups;
    }

GroupInfoList:

    public class GroupInfoList<T> : List<object>
    {
        public object Key { get; set; }

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

Now you are done.

Your GridView will look like this

enter image description here

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top