c# - WPF 使用 MVVM 对集合进行分组

标签 c# .net wpf mvvm observablecollection

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

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

详细信息

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

目标:在环绕面板中,我想创建分组切换按钮。例如,对于北美发现的每只动物,都会有一个带有切换按钮的“北美”GroupBox。接下来,将有一个标题为“Africa”的 GroupBox,该组框内将是非洲的所有动物。

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

最佳答案

在 View 中,将项目源设置为 CollectionViewSource,它本身绑定(bind)到 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

让我知道我是否错过了要点。

关于c# - WPF 使用 MVVM 对集合进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10809278/

相关文章:

c# - 正则表达式匹配字符串中可选的整个单词

c# - 以编程方式创建照片马赛克

wpf - 如何从可编辑的 ComboBox 获取 TextChanged 事件

c# - 将继承类返回到基类 WCF 服务

.net - 更改选定和不集中的列表框样式,使其不灰显

c# - MediaElement 在更改源后播放声音 2 次

c# - 在 Visual Studio 2017 中的 'web site' 中设置 C# 7

c# - Windows 窗体复选框已更改还是已更新?

.net - 使用 WEB API OData v4 调用元数据时出现 404 错误

c# - 如何将小工具集成到我的 .NET 应用程序中