在Windows 8 Metro App中对GridView进行分组

时间:2012-03-25 16:16:05

标签: c# wpf gridview grouping microsoft-metro

有人可以给我一些提示如何完成分组 在GridView for Metro Apps中,如下面的屏幕截图所示。

zoomed out image

此屏幕截图来自Developer Resources for Windows Metro Apps, 但不幸的是,没有描述如何实现它。

我有以下代码段:

的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#:

在Code-Behind中,我在OnNavigateTo方法中执行以下操作:

        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;

无论我做什么,我都无法将项目分组为继续列表 截图。该代码导致并排列出的单独列表。

4 个答案:

答案 0 :(得分:5)

我可能有一个解决方案。在我的项目中,我必须按字母顺序创建联系人列表,例如人物应用程序。

我使用了GridView(使用此sample),CollectionViewSource以及WinRT XAML Toolkit中找到的一个包装带(您可以使用NuGet包或复制/粘贴)源代码)。它允许您将项目放在列中。

示例

enter image description here

<强>视图模型

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();
            }
        }
}

查看

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

答案 1 :(得分:2)

答案 2 :(得分:1)

使用默认网格视图样式无法完成。

您可能必须使用一个非分组项目列表,并添加具有不同项目模板的特殊项目......

抱歉

答案 3 :(得分:1)

我会将标题作为项目添加到gridview,并使用TemplateSelector以正确的方式显示元素...