使用 PagedCollectionView 对 Silverlight DataGrid 中的记录进行分组






4.96/5 (16投票s)
您是否正在使用Silverlight DataGrid并希望以适当的方式对DataGrid中的记录进行分组?如果是这样,本文适合您。在这里,我们将学习DataGrid中的数据分组。
引言
您是否正在使用Silverlight DataGrid
并希望以适当的方式对DataGrid
中的记录进行分组?如果是这样,本文适合您。在这里,我们将学习DataGrid
中的数据分组。在本文中,我们将学习如何在Grid
中分组数据。我们将逐步讨论所有这些,并配有适当的图片,以便您可以非常容易地理解。完整的源代码已附上。您可以免费下载它,这将对您理解更有帮助。阅读完整的文章来学习它。
背景
有时您需要在Silverlight DataGrid
中按列名对数据进行分组。您可能需要多层分组。要做到这一点,您会怎么做?有一个CLR类可以帮助您完成此操作,名为“PagedCollectionView
”。如果您知道要做什么以及如何做,这个类将为您完成所有这些事情。

上面的屏幕截图是我们想要在这里实现的示例。本文旨在帮助您理解此功能以及在您的DataGrid
控件中实现此功能的方法。您不需要编写大量代码,只需少量代码即可完成此操作。让我们开始描述代码。
实现带有记录的基本DataGrid
在进行任何数据分组之前,我们需要创建我们的XAML页面,其中包含一个绑定到ViewModel
中集合的DataGrid
。我知道这对于您来说非常简单。对于我们的示例,我们将创建一个“Employee
”模型,其中包含一些基本属性,例如“Firstname
”、“Lastname
”、“Age
”、“City
”等,如上面的屏幕截图所示。然后,我们将创建一个ServiceProvider
来返回Employee
集合。现在,我们需要实现我们的ViewModel
。创建一个属性,该属性将保存Employee
集合。它将是Employee
类型的ObservableCollection
。在构造函数中,我们将调用EmployeeProviders
以获取Employee
集合。这就是ViewModel
的全部内容。如果您不想,也可以跳过提供程序。但在这种情况下,您必须手动在ViewModel
中填充记录。让我们看看我们刚刚实现的ViewModel
的纯代码
using System.Collections.ObjectModel;
using System.ComponentModel;
using DataGridDemo1.Models;
using DataGridDemo1.Providers;
namespace DataGridDemo1.ViewModels
{
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<Employee> employees;
public ObservableCollection<Employee> Employees
{
get { return employees; }
set
{
employees = value;
OnPropertyChanged("Employees");
}
}
public MainViewModel()
{
// Fetch the Employee Details from provider and set to Employees collection
Employees = EmployeeProviders.GetEmployeeDetails();
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
来到XAML页面。在这里,我们将DataGrid
的ItemsSource
设置为ViewModel
中存在的Employees
集合属性。这是代码
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:DataGridDemo1.ViewModels"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
x:Class="DataGridDemo1.Views.MainView">
<UserControl.Resources>
<viewModels:MainViewModel x:Key="MainViewModel"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid
IsReadOnly="True" Margin="10,40,10,10"
ItemsSource="{Binding Employees, Source={StaticResource MainViewModel}}"/>
</Grid>
</UserControl>
我们的基本DataGrid
已准备好记录。如果您现在运行应用程序,您将看到应用程序具有包含所有字段的Data
记录。除了基本的排序功能,您不会在那里看到任何高级功能。

上图是我们目前为止实现的截图。整个应用程序源代码可供下载。如果您遇到任何问题,可以尝试下载它。
PagedCollectionView 扩展功能
PagedCollectionView
表示一个用于分组、排序、过滤和导航分页数据集合的视图,它属于 System.Windows.Data.dll 程序集。这里列出了 PagedCollectionView
中包含的方法、事件和属性。您可以轻松使用它们。

通过Visual Studio对象浏览器查看所有属性和方法。在这里,我们将讨论使用此类的DataGrid
记录的分组功能。
使用 PagedCollectionView 实现分组
让我们尽可能简单地实现分组。打开您的ViewModel
并更改Employees
集合的属性类型。之前我们使用了ObservableCollection<Employee>
类型,现在只需将其更改为PagedCollectionView
类型。这是您必须执行操作的屏幕截图

现在轮到提供者了。我们正在从EmployeeProvider
获取类型为Employee
的ObservableCollection
集合。因此,在ViewModel
中,不要直接存储在属性中,而是将其转换为PagedCollectionView
。我们的属性也期望相同的类型。为此,通过将整个员工集合传递给构造函数来创建PagedCollectionView
的新实例。类实现将为您处理此问题。

一旦完成此转换,运行您的应用程序。它将成功运行而不会出现任何错误。如果您遇到任何错误,请修复它。在应用程序中,您不会看到任何差异,因为我们尚未实现该功能。我们只是将集合类型转换为不同的类型。在视图模型中创建一个新的public
方法来实现相同的功能。在该方法中,首先清除PagedCollectionView
集合的GroupDescriptions
。
public void GroupDataByColumnName(string groupName)
{
Employees.GroupDescriptions.Clear();
Employees.GroupDescriptions.Add(new PropertyGroupDescription(groupName));
}
然后添加一个带有您要分组的列名的新组描述。上面的代码将根据我们将传递给GroupDataByColumnName()
的参数对数据进行分组,如果您想进行多级分组,您必须向PagedCollectionView
添加两个或更多组描述。对于我们的情况,我们将使用一个ComboBox
修改我们的XAML页面,该ComboBox
将包含组名,即DataGrid
的列名。以下是完整的XAML供您参考
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:DataGridDemo1.ViewModels"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
x:Class="DataGridDemo1.Views.MainView">
<UserControl.Resources>
<viewModels:MainViewModel x:Key="MainViewModel"/>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White"
DataContext="{StaticResource MainViewModel}">
<ComboBox Width="200" Height="20" Margin="10"
HorizontalAlignment="Left" SelectionChanged="ComboBox_SelectionChanged">
<ComboBoxItem Content="City"/>
<ComboBoxItem Content="State"/>
<ComboBoxItem Content="Department"/>
</ComboBox>
<sdk:DataGrid
IsReadOnly="True" Margin="10" ItemsSource="{Binding Employees}"/>
</StackPanel>
</UserControl>
从上面的 XAML 代码,您可以很容易地理解我们做了什么。实现 ComboBox
的 Selection Changed 事件并检索组名。将其传递给 viewmodel
方法以进行分组。以下是用于理解实现的后台代码
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedItem = ((sender as ComboBox).SelectedItem as ComboBoxItem);
var groupName = selectedItem.Content.ToString();
(Resources["MainViewModel"] as MainViewModel).GroupDataByColumnName(groupName);
}
所有实施完成后,我们将能够运行我们的应用程序。
实际演示
现在是时候运行应用程序了。您将看到相同的UI,并额外添加一个ComboBox
。单击combobox
以下拉组名列表。

从下拉列表中选择任何组名,您将看到DataGrid
记录已使用相同的组名正确分组。

更改为不同的组名,您将看到分组在运行时自动更改。无需额外的代码即可实现此功能。PagedCollectionView
为您完成所有操作。

如果您尝试对DataGrid
记录进行排序,您会注意到记录将根据组进行排序。请看下面的截图。在这里,我们根据“Department
”对记录进行了分组。现在,“Age
”上的排序适用于组部门。记录将根据部门进行排序。

如果您想按降序排序,那么它也会根据分组的部门名称进行排序。请查看下图进行确认。

您可以看到,通过使用PagedCollectionView
,所有功能都完美地运行。它是一个符合Silverlight标准的类,您可以根据需要随时使用它。您需要ViewModel
的完整代码吗?好的,在这里
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Data;
using DataGridDemo1.Providers;
namespace DataGridDemo1.ViewModels
{
public class MainViewModel : INotifyPropertyChanged
{
private PagedCollectionView employees;
public PagedCollectionView Employees
{
get { return employees; }
set
{
employees = value;
OnPropertyChanged("Employees");
}
}
public MainViewModel()
{
// Fetch the Employee Details from provider and set to Employees collection
Employees = new PagedCollectionView(EmployeeProviders.GetEmployeeDetails());
}
public void GroupDataByColumnName(string groupName)
{
Employees.GroupDescriptions.Clear();
Employees.GroupDescriptions.Add(new PropertyGroupDescription(groupName));
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
整个源代码以zip文件形式提供下载。如果您愿意,可以单独下载并在Visual Studio IDE中直接查看实现代码。
延伸阅读
结束语
您可以看到,如果您了解该类和实现过程,那么实现起来非常简单。一旦您了解了这一点,实现起来对您来说就非常简单了。关于这个话题还会有更多内容。目前,请尝试该集合视图的其他功能。我很快会发布更多内容。请享受阅读我的文章。最后但同样重要的是,我需要您的反馈/建议来改进我的所有文章。不要忘记写一行评论。如果您有任何疑问,请使用相同的论坛。我会尽快回答您的问题。