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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM