0

DataGridItemsSource是 a ListCollectionView,它有 aGroupDescription和两个SortDescriptions。在程序第一次运行时,一切正常。

但是,当ListCollectionView基于的数据发生更改时,排序ListCollectionView失败(而Grouping没有)。它的行为就好像标记为“LINE A”和“LINE B”的两条线根本不存在。

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();
}

总结一下:

在启动时,一切看起来和行为都像它应该的那样。更改数据,将其保存到DataBase并再次检索它也可以工作。仅对检索到的分组数据进行排序将不起作用(列表按 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

4

2 回答 2

0

我不确定你为什么要在你的虚拟机中制作你ListCollectionView的虚拟机,因为这是PresentationFramework.dll这里没有 MvvM 的一部分。
但是,如果您CollectionViewSource在 xaml 中使用,那么这会容易得多!
在您的 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
于 2017-06-27T09:22:21.013 回答
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
于 2021-02-26T17:10:09.750 回答