Win8中GridVIew千变万化——绑定分组数据

今天和大家探讨下GridView如何绑定分组数据的例子。

要实现分组绑定数据主要两个步骤:
1、创建创建CollectionViewSource并且绑定(这里可以使用两种类型的数据作为数据源,一种使用Linq,另一种使用的时集合中包含集合数据);
2、设置GroupStyle的相关属性和样式。

第一步:创建集合数据源

 public sealed partial class Group : Page
    {
        CollectionViewSource cvsActivities;//, cvsProjects;
        DateTime startDate;//一个界定时间
        public Group()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            DateTime.TryParse("1/1/2014", out startDate);//初始化一个界定时间

            cvsActivities = new CollectionViewSource();
            InitActivities();
            //cvsActivities.Source = InitActivities();
            cvsActivities.IsSourceGrouped = true;
            listView.ItemsSource = cvsActivities.View;

            CollectionViewSource cvsProjects = new CollectionViewSource();
            cvsProjects.Source = InitProjects();
            cvsProjects.IsSourceGrouped = true;
            cvsProjects.ItemsPath = new PropertyPath("Activities");//这里需要指定每组数据子项目的路径
            gridView.ItemsSource = cvsProjects.View;
        }
        private void InitActivities()
        {
            List<Activity> Activities = new List<Activity>();

            Activities.Add(new Activity()
            {
                Name = "Activity 1",
                Complete = true,
                DueDate = startDate.AddDays(4),
                Project = "Project 1"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity 2",
                Complete = true,
                DueDate = startDate.AddDays(5),
                Project = "Project 1"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity 3",
                Complete = false,
                DueDate = startDate.AddDays(7),
                Project = "Project 1"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity 4",
                Complete = false,
                DueDate = startDate.AddDays(9),
                Project = "Project 1"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity 5",
                Complete = false,
                DueDate = startDate.AddDays(14),
                Project = "Project 1"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity A",
                Complete = true,
                DueDate = startDate.AddDays(2),
                Project = "Project 2"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity B",
                Complete = false,
                DueDate = startDate.AddDays(4),
                Project = "Project 2"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity C",
                Complete = true,
                DueDate = startDate.AddDays(5),
                Project = "Project 2"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity D",
                Complete = false,
                DueDate = startDate.AddDays(9),
                Project = "Project 2"
            });
            Activities.Add(new Activity()
            {
                Name = "Activity E",
                Complete = false,
                DueDate = startDate.AddDays(18),
                Project = "Project 2"
            });
            //自己创建分组 使用Linq查询的分组数据
            var result = from act in Activities
                         group act by act.Project into grp
                         orderby grp.Key 
                         select grp;
            cvsActivities.Source = result;
            //return result.ToList<Activity>();//这个方法不能使用
        }

        private List<Project> InitProjects()
        {
            List<Project> Projects = new List<Project>();
            //第一个Project
            Project newProject = new Project();
            newProject.Name = "Project 1";
            newProject.Activities.Add(new Activity() { Name = "Activity 1", Complete = true, DueDate = startDate.AddDays(4) });
            newProject.Activities.Add(new Activity() { Name = "Activity 2", Complete = true, DueDate = startDate.AddDays(5) });
            newProject.Activities.Add(new Activity() { Name = "Activity 3", Complete = false, DueDate = startDate.AddDays(7) });
            newProject.Activities.Add(new Activity() { Name = "Activity 4", Complete = false, DueDate = startDate.AddDays(9) });
            newProject.Activities.Add(new Activity() { Name = "Activity 5", Complete = false, DueDate = startDate.AddDays(14) });
            Projects.Add(newProject);
            //第二个Project
            newProject = new Project();
            newProject.Name = "Project 2";
            newProject.Activities.Add(new Activity() { Name = "Activity A", Complete = true, DueDate = startDate.AddDays(2) });
            newProject.Activities.Add(new Activity() { Name = "Activity B", Complete = false, DueDate = startDate.AddDays(3) });
            newProject.Activities.Add(new Activity() { Name = "Activity C", Complete = true, DueDate = startDate.AddDays(5) });
            newProject.Activities.Add(new Activity() { Name = "Activity D", Complete = false, DueDate = startDate.AddDays(9) });
            newProject.Activities.Add(new Activity() { Name = "Activity E", Complete = false, DueDate = startDate.AddDays(18) });
            Projects.Add(newProject);
            //第三个Project没有子项
            newProject = new Project();
            newProject.Name = "Project 3";
            Projects.Add(newProject);
            return Projects;
            //这里每一个子项目都包含一个子项集合数据
            //cvsProjects.Source = Projects;
            //cvsProjects.ItemsPath = new PropertyPath("Activities");
        }
    }
  public  class Activity
    {
        public string Name { get; set; }
        public DateTime DueDate { get; set; }
        public bool Complete { get; set; }
        public string Project { get; set; }
    }
public  class Project
  {
      public Project()
      {
          Activities = new ObservableCollection<Activity>();
      }

      public string Name { get; set; }
      public ObservableCollection<Activity> Activities { get; private set; }
  }

public class ListGroupStyleSelector : GroupStyleSelector
{
    protected override GroupStyle SelectGroupStyleCore(object group, uint level)
    {
       // Group g = new Group();
        return (GroupStyle)App.Current.Resources["listViewGroupStyle"];//(GroupStyle)g.Resources["listViewGroupStyle"]; //(GroupStyle)App.Current.Resources["listViewGroupStyle"];
    }
}

}

下面讲解下代码和我遇到的问题:
a、里面有两个类Activity和Project;Activity类主要包括一些基本属性,所以在InitActivities方法里面使用的时Linq查询返回的集合数据,Project类里面还包含一个集合数据;
在InitActivities方法中我本来想直接返回List<Activity>,但是当我调用ToList方法的时候报错了;貌似在Win8中不能用还是什么,大家指点下;
b、在创建CollectionViewSource的时候主要注意问题的我们必须设置IsSourceGrouped为true、并且必须制定ItemsPath(Linq查询的可以不需要);在设置数据源的时候我们需要用的是View属性(例: listView.ItemsSource = cvsActivities.View)


第二步:设置GroupStyle

<Page
    x:Class="Win8AppControls.ListViewAndGridView.GridView.Group"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Win8AppControls.ListViewAndGridView.GridView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    
    <Page.Resources>
        <local:ListGroupStyleSelector x:Key="listGroupStyle"/>
    </Page.Resources>

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel Margin="100 50 100 50" Orientation="Horizontal">
            
            <ListView Name="listView"
          ItemTemplate="{StaticResource listViewItemTemplate}"
                      GroupStyleSelector="{StaticResource listGroupStyle}"
           Width="320"/>
            


            <GridView Name="gridView" Margin="20 0">
                <!--设置每一个组里子项目的样式,相当于没有分组前的每一个Item的模板-->
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Margin="20">
                            <TextBlock Text="{Binding Name}" FontWeight="Bold" 
                           Style="{StaticResource ItemTextStyle}"/>
                            <TextBlock Text="{Binding DueDate}" TextWrapping="NoWrap" 
                           Style="{StaticResource BodyTextStyle}" />
                            <CheckBox Content="Complete" IsChecked="{Binding Complete}" 
                          IsEnabled="False"/>
                        </StackPanel>
                    </DataTemplate>
                </GridView.ItemTemplate>
                <!--设置每个组的布局方式-->
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <!--设置分组模版样式包括Head和Container-->
                <GridView.GroupStyle>
                    <!--如果组数据为空则自动隐藏-->
                    <GroupStyle HidesIfEmpty="True">
                        <!--设置头模板-->
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <Grid Background="LightGray" Margin="0">
                                    <!--这里绑定的是分组数据的属性-->
                                    <TextBlock Text='{Binding Name}' 
                                   Foreground="Black" Margin="30"
                                   Style="{StaticResource HeaderTextStyle}"/>
                                </Grid>
                            </DataTemplate>
                            </GroupStyle.HeaderTemplate>
                        <GroupStyle.ContainerStyle>
                            <!--设置每一组的样式-->
                            <Style TargetType="GroupItem">
                                <Setter Property="MinWidth" Value="600"/>
                                <Setter Property="BorderBrush" Value="DarkGray"/>
                                <Setter Property="BorderThickness" Value="2"/>
                                <Setter Property="Margin" Value="3,0"/>
                            </Style>
                        </GroupStyle.ContainerStyle>
                        <!--设置每组里面每一个子项的布局方式-->
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <VariableSizedWrapGrid/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>
        </StackPanel>
    </Grid>
</Page>

在XAML页面我们需要设置:

GridView.ItemTemplate:每一个组里子项目的样式,相当于没有分组前的每一个Item的模板
GridView.ItemsPanel:每个组的布局方式
GridView.GroupStyle:分组模版样式包括Head和Container
GroupStyle.HeaderTemplate:头模板
GroupStyle.ContainerStyle:每一组的样式
GroupStyle.Panel:每组里面每一个子项的布局方式

在这里遇到问题是:我将ListView的GroupStyleSelector写在当前页面通过当前页面实例去获取资源的时候会产生一个StackOverFlow异常,放在App.xaml页面就不会,请指点下;
运行结果

在运行结果上面为什么会出想默认就选择了第一项;难道是使用了CollectionViewSource的缘故吗?因为我没有设置默认选择,求指点。
详细代码大家可以参考MSDN

原文地址:https://www.cnblogs.com/duolete/p/3038356.html