본문 바로가기
개발언어/Windows 8 app

Grouping GridView on Windows 8

by 엔돌슨 2012. 10. 19.
반응형
http://weblogs.asp.net/nmarun/archive/2012/09/15/grouping-gridview-on-windows-8.aspx

기본 템플릿을 사용하여 만드는 과정인데 어떻게 하면 그룹핑할 수 있는지 잘 설명해주고 있다. 데이타를 만들어 그룹핑하면 된다.

Grouping GridView on Windows 8

It took me a few minutes to get the grouping working on the GridView on my Windows 8 app. I’m sharing what I did just so others can get it working sooner and go by the rest of their work.

In VS 2012, I added a Grouped Items Page to my Windows 8 application project.

image

By default, the template will add some sample data, so you can just run it to see how things look. Let’s see what it takes to show our custom data on the page. I’ll stat with the data source.

   1:  public class Team
   2:  {
   3:      public Team(string uniqueId, string teamName, string member, string manager, 
   4:                  int experienceInYears)
   5:      {
   6:          UniqueId = uniqueId;
   7:          TeamName = teamName;
   8:          Member = member;
   9:          Manager = manager;
  10:          ExperienceInYears = experienceInYears;
  11:      }
  12:   
  13:      public string UniqueId { get; set; }
  14:      public string TeamName { get; set; }
  15:      public string Member { get; set; }
  16:      public string Manager { get; set; }
  17:      public int ExperienceInYears { get; set; }
  18:  }
  19:   
  20:  public class TeamDataSource
  21:  {
  22:      public List<Team> Teams { get; set; }
  23:   
  24:      public TeamDataSource()
  25:      {
  26:          Teams = new List<Team>();
  27:   
  28:          Team team = new Team("devTeam", "Dev Team", "Arun", "Vijay", 9);
  29:          Teams.Add(team);
  30:          team = new Team("devTeam", "Dev Team", "Sanjeev", "Vijay", 10);
  31:          Teams.Add(team);
  32:          team = new Team("devTeam", "Dev Team", "Giri", "Sita", 3);
  33:          Teams.Add(team);
  34:          team = new Team("devTeam", "Dev Team", "Dinesh", "Vijay", 6); 
  35:          Teams.Add(team);
  36:   
  37:          team = new Team("testTeam", "Testing Team", "John", "Rubin", 7);
  38:          Teams.Add(team);
  39:          team = new Team("testTeam", "Testing Team", "Vamsi", "Rubin", 5);
  40:          Teams.Add(team);
  41:          team = new Team("testTeam", "Testing Team", "Priyoj", "Babu", 2);
  42:          Teams.Add(team);
  43:      }
  44:  }

I'm going to use the CollectionViewSource in order to bind data to my grid view.

   1:  <CollectionViewSource
   2:      x:Name="groupedItemsViewSource"
   3:      Source="{Binding Groups}"
   4:      IsSourceGrouped="true"/>

My grid view has a very basic design. I have stripped it to the bare minimum, so u don’t see any margins, foreground styles or anything like that.

   1:  <GridView
   2:      x:Name="itemGridView"
   3:      ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}">
   4:      <GridView.ItemTemplate>
   5:          <DataTemplate>
   6:              <Grid HorizontalAlignment="Left" Width="140" Height="140">
   7:                  <StackPanel Orientation="Vertical">
   8:                      <TextBlock Text="{Binding Member}" />
   9:                      <TextBlock>
  10:                          <Run Text="Exp: "/>
  11:                          <Run Text="{Binding ExperienceInYears}" />
  12:                          <Run Text=" yrs"/>
  13:                      </TextBlock>
  14:                      <TextBlock>
  15:                           <Run Text="Manager: "/>
  16:                           <Run Text="{Binding Manager}" />
  17:                      </TextBlock>
  18:                  </StackPanel>
  19:              </Grid>
  20:          </DataTemplate>
  21:      </GridView.ItemTemplate>
  22:      <GridView.ItemsPanel>
  23:          <ItemsPanelTemplate>
  24:              <VirtualizingStackPanel Orientation="Horizontal"/>
  25:          </ItemsPanelTemplate>
  26:      </GridView.ItemsPanel>
  27:      <GridView.GroupStyle>
  28:          <GroupStyle>
  29:              <GroupStyle.HeaderTemplate>
  30:                  <DataTemplate>
  31:                      <Grid>
  32:                          <TextBlock Text="{Binding Key}" />
  33:                      </Grid>
  34:                  </DataTemplate>
  35:              </GroupStyle.HeaderTemplate>
  36:              <GroupStyle.Panel>
  37:                  <ItemsPanelTemplate>
  38:                      <VariableSizedWrapGrid Orientation="Vertical" />
  39:                  </ItemsPanelTemplate>
  40:              </GroupStyle.Panel>
  41:          </GroupStyle>
  42:      </GridView.GroupStyle>
  43:  </GridView>

The lines 31-33 is the grid that defines the header of the grid view and the lines 6-19 render the item itself. Line 32 says that we’ll be binding the ‘Key’ element as the header element. There is no ‘Key’ property in our data source classes. We’ll see that from the code below, where the binding actually happens.

   1:  protected override void LoadState(Object navigationParameter, 
   2:                                    Dictionary<String, Object> pageState)
   3:  {
   4:      TeamDataSource teamlist = new TeamDataSource();
   5:      var teamGroups = teamlist.Teams.GroupBy(team=>team.TeamName)
   6:                                     .OrderBy(team => team.Key.ToString());
   7:   
   8:      DefaultViewModel["Groups"] = teamGroups;
   9:  }

The ‘Key’ is actually added by grouping. It basically means that the data is being ‘pivoted’ on some key, which in this case is the TeamMember property.

image

The benefit of doing it this ways is that we can group by some combination of the properties. We can always say, I’d like to group it by team name AND manager.

   1:  var teamGroups = teamlist.Teams.GroupBy(team => team.TeamName + "-" + team.Manager)
   2:                                 .OrderBy(team => team.Key.ToString());

image

You may have observed that our data source is pretty flat and it might not be the case all the time. Data usually comes in a hierarchical fashion. Let’s take that example as well.

   1:  public class Team
   2:  {
   3:      public Team(String member, String manager, 
   4:                  int experienceInYears)
   5:      {
   6:          Member = member;
   7:          Manager = manager;
   8:          ExperienceInYears = experienceInYears;
   9:      }
  10:   
  11:      public string Member { get; set; }
  12:      public string Manager { get; set; }
  13:      public int ExperienceInYears { get; set; }
  14:  }
  15:   
  16:   
  17:  public class TeamDetail
  18:  {
  19:      public string TeamName { get; set; }
  20:      public List<Team> Teams { get; set; }
  21:  }
  22:   
  23:  public class TeamDetailsSource
  24:  {
  25:      public List<TeamDetail> TeamDetails { get; set; }
  26:   
  27:      public TeamDetailsSource()
  28:      {
  29:          TeamDetails = new List<TeamDetail>();
  30:          TeamDetail teamDetail = new TeamDetail{ TeamName = "Devs team" };
  31:          TeamDetails.Add(teamDetail);
  32:   
  33:          teamDetail.Teams = new List<Team>();
  34:          Team team = new Team("Arun", "Vijay", 9);
  35:          teamDetail.Teams.Add(team);
  36:          team = new Team("Sanjeev", "Vijay", 10);
  37:          teamDetail.Teams.Add(team);
  38:          team = new Team("Giri", "Sita", 3);
  39:          teamDetail.Teams.Add(team);
  40:          team = new Team("Dinesh", "Vijay", 6);
  41:          teamDetail.Teams.Add(team);
  42:   
  43:          teamDetail = new TeamDetail { TeamName = "Test team" };
  44:          teamDetail.Teams = new List<Team>();
  45:          TeamDetails.Add(teamDetail);
  46:          team = new Team("John", "Rubin", 7);
  47:          teamDetail.Teams.Add(team);
  48:          team = new Team("Vamsi", "Rubin", 5);
  49:          teamDetail.Teams.Add(team);
  50:          team = new Team("Priyoj", "Babu", 2);
  51:          teamDetail.Teams.Add(team);
  52:      }
  53:  }

This is a typical hierarchical collection that I have.

The way I’ll be binding my data is by just initializing the collection.

   1:  var teamGroups = new TeamDetailsSource().TeamDetails;
   2:   
   3:  DefaultViewModel["Groups"] = teamGroups;

There is one other change that we’ll have to do to our CollectionViewSource. We need to provide the path for the collection where the items exist. This is done by setting the ItemsPath property. The ItemDetails class as a property called Teams which is what needs to be passed to the ItemsPath setting.

   1:  <CollectionViewSource
   2:      x:Name="groupedItemsViewSource"
   3:      Source="{Binding Groups}"
   4:      IsSourceGrouped="true"
   5:      ItemsPath="Teams"/>

image

IT JUST HAS TO WORK!

Published Saturday, September 15, 2012 8:30 AM by nmarun