在XAML中为ItemsControl定义分组,适合mvvm绑定

可以先参考一下这个文章:

http://www.cnblogs.com/zoexia/archive/2014/11/30/4134012.html



step0: 先展示一下最简陋的界面:

上图是一个控件容器:ListBox,每一项都是一个Student的学生数据,它继承自ItemsControl,所以是可以实现分组的。容器内每个组用Expander可伸缩控件表示。
请保证已经完全理解图中所有控件和数据的含义,然后再进行下一步。



step1: 首先,我们从dataContext数据源入手,因为它是根本:

//我们虚拟一个“学校Id”作为将来的分组依据
public class Student
{
      public int Id { get; set; }
      public string Name { get; set; }
      public int SchoolId { get; set; }
}

//然后在ViewModel里准备数据源
        private ObservableCollection<Student> _Students;
        /// <summary>
        /// 绑定通知,学生列表
        /// </summary>
        public ObservableCollection<Student> Students
        {
            get { return _Students; }
            set
            {
                if (_Students == value) { return; }
                _Students = value;
                NotifyOfPropertyChange(() => Students);
            }
        }

上述代码用到的是MVVM模式,如果你不熟悉, 请学习一下,推荐“刘铁猛”的那个mvvm入门视频,讲的很棒!
如果还看不懂,我只能说代码是两块,一块是基础Model,一块是扔在绑定源里的一个支持属性通知的成员。



step3: 在view里获取绑定源

        <CollectionViewSource x:Key="studentsSource" Source="{Binding Students}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="SchoolId" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>

由于我们的绑定源(Students)现在需要分组,所以,你需要定义,这里的 CollectionViewSource 是在View里处理列表数据源很好用的一个东西,俗称“数据集的视图”,记住所有的ItemsControl其实数据源都是来自于它,意思就是所有的列表控件都有一个“数据集的视图”,以前我们没用过的话,默认都是一个“Default”值,比如,分组功能,那就是GroupStyle.Default。
我以前也有个让DataGrid支持显示行Index的,就是用到了“数据集的视图”,有兴趣的可以去翻阅。

<ListBox ItemsSource="{Binding Source={StaticResource studentsSource}}" Height="300" Width="200">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=Name}"/>
                <TextBlock Text="{Binding Path=Id}"/>
                <TextBlock Text="{Binding Path=SchoolId}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这里是为了让ListItem的每一列显示成指定的布局,除了让ItemsSource获取我们自己定义的视图资源,其他并无区别。
那么,问题来了!(最近挺流行这句话的)分组的布局是用什么显示的呢?答案就是“ItemsControl.GroupStyle”属性了,那下面我们就开始定义一个Style

<ListBox.GroupStyle>
    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <Expander IsExpanded="True">
                                <Expander.Header>
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock Text="{Binding Name}" VerticalAlignment="Center" />
                                        <TextBlock Text="{Binding ItemCount, StringFormat=数量:{0}}"
                                           VerticalAlignment="Center" Margin="5,0,0,0" />
                                        <Button Content="点我" Margin="5,0,0,0" />
                                    </StackPanel>
                                </Expander.Header>
                                <ItemsPresenter />
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
</ListBox.GroupStyle>

既然是为“GroupStyle”属性订制自定义容器,那它的数据源就肯定和“ItemsSource”不一样了,它的类型是“MS.Internal.Data.CollectionViewGroupInternal”,派生自CollectionViewGroup类型。
我们先看看这个类里为数不多的几个属性:

Items:我们知道的列表容器里ItemsSource属性绑过来的数据其实经过的那道程序,数据源就来自它。
ItemCount:其实就是Items属性里面资源的个数。
Name:分组的名称,其实就是前面绑定的“学校Id”的真实值

大家也看出来了,其实分组容器是和真实数据无关的(除了组名,也就是学校Id,不过它是在分组之前就给定的,和Items里面的真实值无关)。



好了,over,其实就是分4小步:

1,先准备数据源,这里是Students
2,为数据源添加自定义视图,这里是CollectionViewSource
3,添加显示列表控件,并获取带视图的源
4,定义GoupStyle

时间: 2024-11-06 06:04:01

在XAML中为ItemsControl定义分组,适合mvvm绑定的相关文章

XAML中ContentControl,ItemsControl,DataTemplate之间的联系和区别

接触XAML很久了,但一直没有深入学习.今天学习了如标题所示的内容,所以来和大家分享一下,或者准确的说是自我回顾一遍. 在XAML中,有两类我们常见的控件,分别是ContentControl和ItemsControl,典型的标识是一个有Content属性,另一个有Items属性. 一:ContentControl 我们平时最常见的该类型控件有Button,RadioButton,CheckBox等.一般有Content属性的都是这类控件.在该类控件中,有一个属性便是ContentTemplate

如何在.cs中统一动态修改xaml中style资源定义的样式

关于设置控件属性样式的方法已经在之前的博客中有提及过,博客地址:设置控件样式的方法 当然在实际项目编写过程中,不光单纯的需要设置元素样式,有时候需要动态的修改元素的样式,这个时候就有些不 同了.需要针对不同的情形来选择不同的方法修改样式. 情形一:单纯的修改一个控件元素的样式,那么只要在.cs中仅仅针对这个控件的样式属性的修改即可. 情形二:如果是要针对同一类的所有控件的样式进行相同的属性修改,比如针对页面中所有的Label控件进行修改, 那么对应之前你在给这些Label控件设置样式的不同做法,

Xaml中string(字符串)常量的定义以及空格的处理

(1)基本用法 xaml中可以实例化各种对象,比如在ResourceDictionary中定义字符串常量: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system ="clr-namespace:Sy

关于JS中的函数定义及函数表达式

在初学JS的过程中,老是不能区别什么是函数表达式什么是函数定义,这对基础知识的夯实是不利的.因此查阅资料,认真对其进行了区别. 简单总结如下: 1.区别一:以function开头的函数纪委函数定义,其他则为函数表达式: 2.区别二:函数表达式可以省略函数名. function FunctionName(FormalParameterList) { FunctionBody } //函数定义 function [FunctionName](FormalParameterList) { Functi

Hadoop学习笔记—11.MapReduce中的排序和分组

一.写在之前的 1.1 回顾Map阶段四大步凑 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排序和分组,默认情况下,是按照key进行排序和分组. 1.2 实验场景数据文件 在一些特定的数据文件中,不一定都是类似于WordCount单次统计这种规范的数据,比如下面这类数据,它虽然只有两列,但是却有一定的实践意义. 3 3 3 2 3 1 2 2 2 1 1 1 (1)如果按照第一列升序排列,当

WPF里ItemsControl的分组实现

我们在用到ItemsControl时,有时会用到分组,如ListBox,ListView,DataGrid.WPF的ItemsControl可以实现分组,是依托于GroupStyle,以ListBox为例,他的分组效果图为: 以下为前台: 1 <ListBox Name="lbMain"> 2 <ListBox.ItemTemplate> 3 <DataTemplate> 4 <StackPanel Orientation="Hori

[UWP]xaml中自定义附加属性使用方法的注意项

---恢复内容开始--- 随笔小记,欢迎指正 在UWP平台上做WVVM的时候,想针对ListBox的SelectionChanged事件定义一个自定义的命令,于是使用自定义附加属性的方式.可是最后自定义附加属性SelectionChangedCommand写好了,却不知道怎么在XAML中使用. 我的自定义属性如下: namespace SelectionChangedCommand.Services { public static class SelectionChangedBehavior {

stm32工程建立中关于宏定义和启动文件的选择

在STM32的学习过程中,第一步关于stm32工程的建立就会难倒很多人,因为他不像其他AVR 51单片机这些,options中的配置比较复杂,其中最让人头疼的就是关于c/c++ compiler选项中preprocessor这个选择框,现在我就对其中的两项进行说明,一是为了让以后学习STM32的同学能更快的了解,二是为了让我自己更好的复习. 如上图所示  其中 additional include directories下面的框需要添加工程内头文件所在的路径,'$PROJ_DIR$'表示的是工程

【WinRT】【译】【加工】在 XAML 中制作圆形图片

原文地址:http://timheuer.com/blog/archive/2015/05/06/making-circular-images-in-xaml-easily.aspx 前阵子似乎一些比较酷的程序开始使用圆形头像来取代之前方形或者圆角边的显示方式了.我(原文作者.下文中如果没特别提到,均指原文作者)在两年前注意到一些 App 开始这样做的时候,做出了一个偏激的发言: 看看吧,程序里会越来越多圆形的头像了,方形的将不会再有了 ——Tim Heuer(@timheuer) 2013 年