WPF Datagrid:在更改数据后,ListCollectionView排序似乎不起作用

时间:2017-06-27 08:40:54

标签: c# wpf sorting datagrid listcollectionview

我的DataGrid ItemsSourceListCollectionView,其中GroupDescriptionSortDescriptionsListCollectionView。在程序的第一次运行中,一切都按预期工作。

但是,当基于ListCollectionView的数据发生变化时,Grouping的排序失败(而public List<MyModel> Models { get; set; } public ListCollectionView _collectionView; public MyConstructor() { InitializeComponent(); GetData(); Grouping(); } public void GetData() { // fill the list "Models" } public void Grouping() { // _collectionView = null; _collectionView = new ListCollectionView(Models); _collectionView.GroupDescriptions.Add(new PropertyGroupDescription("MyModelSupplier")); _collectionView.SortDescriptions.Add(new SortDescription("MyModelSupplier", ListSortDirection.Ascending)); // LINE A _collectionView.SortDescriptions.Add(new SortDescription("MyModelName", ListSortDirection.Ascending)); // LINE B ModelControl.ItemsSource = _collectionView; } private void OnDataChanged (object sender, EventArgs e) { // Save the Data to the Database //... // Retrieve the Data GetData(); // Group it again Grouping(); } 则没有)。它表现得好像标记为“LINE A”和“LINE B”的两条线根本不存在。

DataBase

总结:

在启动时,一切都看起来和行为应该如此。更改数据,将其保存到 Col1 Col2 1 NaN Someval1 2 Y Someval2 3 N Someval3 4 NaN NaN 5 NaN Someval4 并再次检索它也可以。只是对检索到的分组数据进行排序是行不通的(列表是按默认方式排序的 - 由MyModel类的第一个属性,即MyModelName ...而不是MyModelSupplier,就像它在最开始时那样)

修改 这是一个已知的错误/缺失功能(直到.NET 4.6.2)。可以在这里找到几个建议(我选择了最后一个解决方案):

错误报告:https://connect.microsoft.com/VisualStudio/feedback/details/2017716/wpf-live-shaping-groups-are-not-sorted-correctly-after-a-property-changes

简单修复:https://stackoverflow.com/a/10121983/8187945

2 个答案:

答案 0 :(得分:0)

我不确定你为什么要在你的虚拟机中ListCollectionView,因为这是PresentationFramework.dll的一部分,所以这里没有MvvM。
但是,如果您在xaml中使用CollectionViewSource,那么这将更加容易! 在你的xaml中你会做:

<CollectionViewSource Source="{Binding Items}" x:Key="items">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="yourPropertyHere"/>
    </CollectionViewSource.GroupDescriptions>
    <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="propertyHere" />
    </CollectionViewSource.SortDescriptions>
    <CollectionViewSource.LiveFilteringProperties>
        propertyNameHere
    </CollectionViewSource.LiveFilteringProperties>
</CollectionViewSource>  

其中:

xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"  

然后将其用于DataGrid,如此:
<DataGrid ItemsSource="{Binding Source={StaticResource events}}"/>

这使您能够在xaml中远离视图模型使用这些选项 您也可以在后面的代码中执行此操作:
XAML:

<CollectionViewSource x:Key="MyCVS"
                          Source="{Binding Items}"
                          Filter="My_Filter" />  

然后在你的代码中:

void My_Filter(object sender, FilterEventArgs e)
{
    var item = e.Item as yourModelObject;
    if (item == <your test here>)
    {
        e.Accepted = true;
    }
    else
    {
        e.Accepted = false;
    }
}  

如果您仍然无法刷新视图,那么您可以在后面的代码中使用它来访问正在显示的项目并刷新:

CollectionViewSource.GetDefaultView(lst.ItemsSource).Refresh();// where lst would be ListView or DataGrid

答案 1 :(得分:0)

老实说,我浪费了我一生中的六个小时。 SortDescriptions 第一次工作,我无法实施我在某处找到的所有提供的解决方案。

我决定使用 CustomSort。五分钟后,我完成了。所以,如果你读到这里,也许你会节省时间

解决方案 1 部分:

public class MyComparer : IComparer
{
    public int Compare(object x, object y)
    {
        var a = x as CustomViewEntityViewModel;
        var b = y as CustomViewEntityViewModel;

        if (a == null || b == null)
            throw new ArgumentException("Not My CustomViewEntityViewModel");

        if (a.SortOrder > b.SortOrder)  // I added property SortOrder to my viewmodel
            return 1;
        if (a.SortOrder == b.SortOrder)
            return 0;

        return -1;
    }
}

第二部分:如何使用

var myListCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(Filters);
myListCollectionView.CustomSort = new MyComparer();
myListCollectionView.GroupDescriptions.Add(new PropertyGroupDescription("Category"));

MyListCollectionView = myListCollectionView; // Which is binded by DG.ItemsSource