使用MVVM对集合进行WPF分组

时间:2012-05-30 02:34:25

标签: c# .net wpf mvvm observablecollection

我是WPF和MVVM的新手,所以如果这是一个愚蠢的问题,我会提前请求原谅。

问题: 我正在尝试使用MVVM设计模式创建一个分组的项目列表。我可以用代码来做,但更喜欢更优雅的解决方案。

详细

  • 假设我有一群动物:马,狼,猴子,老虎,北极熊,斑马,蝙蝠等。
  • 这些动物按大洲分组:北美洲,非洲,南极洲等。

目标:在换页面板中,我想创建分组切换按钮。例如,对于在北美发现的每种动物,将会有一个带有ToggleButtons的“北美”GroupBox。接下来,会有一个标题为“非洲”的GroupBox,而在组合框中则是非洲的所有动物。

使用MVVM设计模式,我可以绑定到ObservableCollection,并使用数据模板创建我需要的切换按钮。在我挣扎的地方,我不知道如何将动物分组。我需要的只是指导方针。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:13)

在视图中,将项目源设置为CollectionViewSource,CollectionViewSource本身绑定到ViewModel上的Animals集合。 CollectionViewSource可以分组,如下所示:

<CollectionViewSource.GroupDescriptions>
   <PropertyGroupDescription PropertyName="Continent" />
</CollectionViewSource.GroupDescriptions>

您还需要在您拥有的任何项目控件上设置组样式 - 类似这样的

<ItemsControl.GroupStyle>
   <GroupStyle>
      <GroupStyle.HeaderTemplate>
         <DataTemplate>
            <TextBlock FontWeight="Bold" FontSize="15"
               Text="{Binding Path=Name}"/>
         </DataTemplate>
      </GroupStyle.HeaderTemplate>
   </GroupStyle>
</ItemsControl.GroupStyle>

摘自此页面上的示例 - http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.groupstyle.aspx

这是设置HeaderTemplate,但如果你玩一下,你应该能够为每个组设置一个容器样式。

希望这有帮助!

<强>更新 我对此并不太确定,所以我对代码进行了快速反击。假设“切换按钮”是“单选按钮”,这就是我想出的:

<Grid>
    <Grid.Resources>
        <CollectionViewSource x:Key="Animals" Source="{Binding}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Continent" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Grid.Resources>

    <ItemsControl ItemsSource="{Binding Source={StaticResource Animals}}">
        <ItemsControl.GroupStyle>
            <x:Static Member="GroupStyle.Default" />
        </ItemsControl.GroupStyle>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <RadioButton Content="{Binding Name}" GroupName="{Binding Continent}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

此外,您可以将行<x:Static Member="GroupStyle.Default" />替换为:

,将每个组显示为GroupBox
<GroupStyle>
   <GroupStyle.ContainerStyle>
      <Style TargetType="{x:Type GroupItem}">
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate>
                  <GroupBox Margin="10" Header="{Binding Name}">
                     <GroupBox.Content>
                        <ItemsPresenter />
                     </GroupBox.Content>
                  </GroupBox>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </GroupStyle.ContainerStyle>
</GroupStyle>

但是,单选按钮本身并不相互排斥(我认为是因为它们包含在ListItem控件中,或者其他使它们成为分组父单元的子节点的东西)。如果您想要返回获取更多信息(他们的示例包含显示/隐藏组的扩展器),则该代码在MSDN中的GroupStyle条目中被盗/修改:http://msdn.microsoft.com/en-us/library/system.windows.controls.groupstyle.aspx

如果我完全错过了这一点,请告诉我。

答案 1 :(得分:-1)