我在 WPF / .Net Framework 4.8 和 Prism for MVVM 上有一个应用程序。我不明白如何使用 MVVM 对数据网格中的项目进行分组。我发现的所有指南都仅在没有 MVVM 的情况下实现了此功能。使用 MVVM 找到的唯一一个对我不起作用(没有错误,但数据网格中也没有组)
主窗口有一个包含以下对象的数据网格:
Product p = new Product() {
Id = "H196A", //Any string
Name = "Box A", //Any string
Count = 3 //Any int
}
ViewModel 看起来像这样
public ObservableCollection<Product> MyCollection { get; set; }
public ViewModel()
{
//Filling in the collection
}
并查看
<DataGrid ItemsSource="{Binding MyCollection}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Id"/>
<DataGridTextColumn Header="Name"/>
<DataGridTextColumn Header="Count"/>
</DataGrid.Columns>
</DataGrid>
我尝试通过这种方式将数据网格绑定到 CollectionViewSource:
public CollectionViewSource MyCollectionViewSource { get; set; }
public ViewModel()
{
//Filling in the collection
MyCollectionViewSource = new CollectionViewSource();
MyCollectionViewSource.Source = MyCollection;
MyCollectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription(nameof(Product.Name)));
}
<DataGrid ItemsSource="{Binding MyCollectionViewSource.View}" AutoGenerateColumns="False">
...
</DataGrid>
但是没有成功
CollectionViewSOurce
定义为静态资源更容易。作为解释,
<Grid.Resources>
只是一个字典,允许使用您定义的
key
引用静态对象,因此在本例中,键是
GroupedProducts
。
<Window x:Class="data_grid_grouping.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:data_grid_grouping"
mc:Ignorable="d"
Background="Azure"
Title="MainWindow" Width="500" Height="500" >
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid>
<Grid.Resources>
<CollectionViewSource x:Key="GroupedProducts" Source="{Binding MyCollection}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Name"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Grid.Resources>
<DataGrid ItemsSource="{Binding Source={StaticResource GroupedProducts}}" AutoGenerateColumns="False" Margin="10, 5">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="*" />
<DataGridTextColumn Header="Count" Binding="{Binding Count}" />
<DataGridTextColumn Header="Id" Binding="{Binding Id}" />
</DataGrid.Columns>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="14" Text="{Binding Name}" Margin="5" Foreground="Maroon"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow() => InitializeComponent();
}
class ViewModel : BindableBase
{
public ViewModel()
{
var tmp = MyCollection.GroupBy(_=>_.Name);
foreach (var tmpGroup in tmp)
{
var count = 1;
foreach (Product product in tmpGroup)
{
product.Count = count++;
}
}
}
public ObservableCollection<Product> MyCollection { get; } = new ObservableCollection<Product>
{
new Product{ Name = "Hammer" },
new Product{ Name = "Screwdriver Set" },
new Product{ Name = "Drill Bit Set" },
new Product{ Name = "Measuring Tape" },
new Product{ Name = "Wrench" },
new Product{ Name = "Drill Bit Set" },
new Product{ Name = "Hammer" },
new Product{ Name = "Wrench" },
new Product{ Name = "Drill Bit Set" },
new Product{ Name = "Hammer" },
new Product{ Name = "Screwdriver Set" },
new Product{ Name = "Measuring Tape" }
};
public event PropertyChangedEventHandler? PropertyChanged;
}
public class Product : BindableBase
{
private int _count;
public int Count
{
get => _count;
set => SetProperty(ref _count, value);
}
private string _name = string.Empty;
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private string _id = Guid.NewGuid().ToString().ToLower().Replace("-", string.Empty);
public string Id
{
get => _id;
set => SetProperty(ref _id, value);
}
}