【问题标题】:PropertyGroupDescription CustomSort is missing the ItemCount in item XPropertyGroupDescription CustomSort 缺少项目 X 中的 ItemCount
【发布时间】:2023-01-04 23:29:10
【问题描述】:

前言: 首先,我搜索了 stackoverflow,所有与排序分组数据网格相关的主题都不适用于这个问题。事实上,没有一个答案实际上显示了如何在不使用第 3 个部分库的情况下按组计数进行排序。

问题: 我试图通过覆盖 PropertyGroupDescription 的 CustomSort 属性来按计数对我的数据网格组进行排序。当我将 CustomSort 方法分配给 GroupDescription 时,Compare 函数的对象 x CollectionViewGroup 始终具有 ItemCount == 0。

这是我的示例 xaml,主要取自 Microsoft 的帮助:

<Window 
    x:Class="GroupedSorting.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:GroupedSorting"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>

        <DataGrid
            Name="dg"
            Grid.Row="0"
            ItemsSource="{Binding ItemVMs}">

            <DataGrid.GroupStyle>
                <!-- Style for groups at top level. -->
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Margin" Value="0,0,0,5"/>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <Expander IsExpanded="True" Background="#FF112255" BorderBrush="#FF002255" Foreground="#FFEEEEEE" BorderThickness="1,1,1,5">
                                            <Expander.Header>
                                                <DockPanel>
                                                    <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
                                                    <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
                                                </DockPanel>
                                            </Expander.Header>
                                            <Expander.Content>
                                                <ItemsPresenter />
                                            </Expander.Content>
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
                <!-- Style for groups under the top level. -->
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <DockPanel Background="LightBlue">
                                <TextBlock Text="{Binding Path=Name, Converter={StaticResource completeConverter}}" Foreground="Blue" Margin="30,0,0,0" Width="100"/>
                                <TextBlock Text="{Binding Path=ItemCount}" Foreground="Blue"/>
                            </DockPanel>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </DataGrid.GroupStyle>
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <Setter Property="Foreground" Value="Black" />
                    <Setter Property="Background" Value="White" />
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
    </Grid>
</Window>

这是背后的代码:

using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Data;

namespace GroupedSorting
{
    public partial class MainWindow : Window
    {
        public ObservableCollection<MyViewModel> ItemVMs { get; set; } = new ObservableCollection<MyViewModel>();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

            for (int i = 0; i < 10; i++)
            {
                ItemVMs.Add(new MyViewModel()
                {
                    Name = "Group 1",
                    MyIndex = i,
                });
            }

            for (int i = 0; i < 5; i++)
            {
                ItemVMs.Add(new MyViewModel()
                {
                    Name = "Group 2",
                    MyIndex = i,
                });
            }

            for (int i = 0; i < 1; i++)
            {
                ItemVMs.Add(new MyViewModel()
                {
                    Name = "Group 3",
                    MyIndex = i,
                });
            }


            Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var sourceView = CollectionViewSource.GetDefaultView(dg.ItemsSource);
            var gd = new PropertyGroupDescription(nameof(MyViewModel.Name));
            gd.CustomSort = new GroupComparer();
            sourceView.GroupDescriptions.Add(gd);
            sourceView.Refresh();
        }
    }

    public class MyViewModel
    {
        public string Name { get; set; }
        public int MyIndex { get; set; }
    }

    public class GroupComparer : System.Collections.IComparer
    {
        public int Compare(object x, object y)
        {
            if (!(x is CollectionViewGroup xViewGroup))
                return 0;

            if (!(y is CollectionViewGroup yViewGroup))
                return 0;

            Debug.WriteLine($"{xViewGroup.Name} {xViewGroup.ItemCount }, {yViewGroup.Name} {yViewGroup.ItemCount}");

            if (xViewGroup.ItemCount < yViewGroup.ItemCount)
                return 1;
            else if (xViewGroup.ItemCount > yViewGroup.ItemCount)
                return -1;

            return 0;
        }
    }
}

运行代码时,xViewGroup.ItemCount 始终等于 0,导致排序方法失败。

【问题讨论】:

    标签: wpf datagrid


    【解决方案1】:

    将从CollectionViewSource.GetDefaultView 返回的ICollectionView 转换为ListCollectionView,并将这个的CustomSort 属性设置为您自定义的IComparer

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        var sourceView = CollectionViewSource.GetDefaultView(dg.ItemsSource) as ListCollectionView;
        var gd = new PropertyGroupDescription(nameof(MyViewModel.Name));
        sourceView.CustomSort = new GroupComparer();
        sourceView.GroupDescriptions.Add(gd);
        sourceView.Refresh();
    }
    

    【讨论】:

    • 这会产生相同的结果。对象 x 计数始终为 0。
    • 我不得不完全放弃 Microsoft 的实施,而是在我的视图模型中进行排序。因此,要更改排序顺序,对视图模型进行排序,然后从头开始重新加载视图。
    • 我可能误解了你的问题,但它对我有用。但是自己进行分类通常是个好主意。
    • 你试过上面的示例代码了吗?它不起作用:(
    • 我不确定您看到了什么错误,但是我为 .Net 4.7.2 创建了一个简单的 WPF 应用程序,然后使用了上面的代码。它对我有用,所以我需要更多信息。
    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多