wpf MVVM 动态 DataGrid 排序过滤

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16200622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:40:34  来源:igfitidea点击:

MVVM Dynamic DataGrid Sorting Filtering

c#wpfmvvmdatagridfiltering

提问by ncourcy84

I have a DataGridthat gets its data updated every few seconds via a Thread. The DataGridneeds to offer Column Header sorting, grouping and filtering.

我有一个DataGrid通过Thread. 所述DataGrid提供列标题需要排序,分组和过滤。

I currently have a DataGridbound to a ICollectionViewand the source of the ICollectionViewis an ObservableCollection. Which seems to be the good way to do it from what I read on other threads.

我目前DataGrid绑定到 aICollectionView并且源ICollectionView是 a ObservableCollection。这似乎是我在其他线程上阅读的内容的好方法。

The sort-ing "works" but it gets lost when the ICollectionView.Sourcegets updated following an update of the ObservableCollection. I have tried saving the SortDescriptionsbefore the update and re-add it to the ICollectionViewafter the update is done. But it's the same result.

排序“有效”,但ICollectionView.Source在更新ObservableCollection. 我尝试SortDescriptions在更新前保存并ICollectionView在更新完成后将其重新添加到。但结果是一样的。

May someone point me to what I'm missing?

有人可以指出我缺少的东西吗?

Edit Here's some code...

编辑这是一些代码...

View (XAML)

查看 (XAML)

<DataGrid ItemsSource="{Binding CollectionView, Source={StaticResource ViewModel}}>

ViewModel

视图模型

public ICollectionView CollectionView
{
    get
    {
        collectionViewSource.Source = dataColl;
        if (SortDescriptions != null)
        {
            foreach (SortDescription sd in SortDescriptions)
            {
                collectionViewSource.View.SortDescriptions.Add(sd);
            }
        }
        collectionViewSource.View.Refresh();
        return collectionViewSource.View;
    }
}

public ObservableCollection<SomeObject> DataColl
{
    get { return dataColl; }
    private set 
    {
        this.dataColl= value;
        OnPropertyChanged("CollectionView");
    }
}

Following is the method that updates the data every few seconds...

以下是每隔几秒更新一次数据的方法...

private void UpdateData()
{
    while (true)
    {
        System.Threading.Thread.Sleep(mDataRefreshRate);

        // SortDescriptions is a Property of the ViewModel class.
        SortDescriptions = collectionViewSource.View.SortDescriptions;

        ObservableCollection<SomeObject> wDataColl
           = new ObservableCollection<SomeObject>();

        //... Irrelevant code that puts the data in wDataColl ...

        DataColl= wDataColl;
    }
}

采纳答案by Mark Homer

[YourObservableCollection].ViewHandler.View.Filter
                    += new FilterEventHandler(myFilterHandler);

private void myFilterHandler(object sender, FilterEventArgs e)
{
}

Can be used to directly add your filter handler and you can do the same with SortDescriptionsto Add/Remove

可用于直接添加您的过滤器处理程序,您可以SortDescriptions对添加/删除执行相同的操作

[YourObservableCollection].ViewHandler.View.SortDescriptions.Add(mySortDescription);

If you are doing allot of sorting and filtering best to create own class encapsulating a CollectionViewSource and implement adding and removing SortDescriptionsand Filtering etc

如果您正在执行分配的排序和过滤,最好创建自己的类封装 CollectionViewSource 并实现添加和删除SortDescriptions和过滤等

When you say:

当你说:

The sort "works" but it gets lost when the ICollectionView.Source gets updated following an update of the ObservableCollection

排序“有效”但是当 ICollectionView.Source 在 ObservableCollection 更新后更新时它会丢失

What do you mean by update? you mean you are changing the Source? Rather than adding/removing items from the collection?

你说的更新是什么意思?你的意思是你正在改变源?而不是从集合中添加/删除项目?

EDIT based on your XAML example you added:

根据您添加的 XAML 示例进行编辑:

<DataGrid ItemsSource="{Binding CollectionView, Source={StaticResource ViewModel}}>

You are binding itemsource to the CollectionViewSource where you should bind the datacontext to it:

您将 itemsource 绑定到 CollectionViewSource,您应该将数据上下文绑定到它:

Example:

例子:

<Page.Resources>
    <CollectionViewSource x:Key="myViewSource"
          Source="{Binding CollectionView, Source={StaticResource ViewModel}}"
    />
</Page.Resources>

In page:

在页面:

<Grid DataContext="{StaticResource myViewSource}">

        <DataGrid x:Name="myGrid"  ItemsSource="{Binding}"...

Or something along those lines

或类似的规定

EDIT again didnt see code scroll down :p

再次编辑没有看到代码向下滚动:p

ObservableCollection<SomeObject> wDataColl= new ObservableCollection<SomeObject>();

You create new instance every time of collection lol this is main problem

每次收集时都会创建新实例哈哈这是主要问题

Also:

还:

public ICollectionView CollectionView
{
    get
    {
        collectionViewSource.Source = dataColl;
        if (SortDescriptions != null)
        {
            foreach (SortDescription sd in SortDescriptions)
            {
                collectionViewSource.View.SortDescriptions.Add(sd);
            }
        }
        collectionViewSource.View.Refresh();
        return collectionViewSource.View;
    }
}

Here where you return collection you are setting the Sourceand adding the SortDescriptionsand also refreshing the view every time, you only need set these values once

在这里您返回集合,您正在设置Source和添加SortDescriptions以及每次刷新视图,您只需要设置一次这些值

You would only call refresh on the View if you add/remove SortDescriptions

如果您添加/删除,您只会在视图上调用刷新 SortDescriptions

I think you should get to grips with basics of CollectionViewSource

我认为你应该掌握CollectionViewSource 的基础知识

回答by Niclas

The problem is that you swap out the entire ObservableCollection every time you add new data.

问题是每次添加新数据时都要换掉整个 ObservableCollection。

    ObservableCollection<SomeObject> wDataColl= new ObservableCollection<SomeObject>();

    ... Unrelevant code that puts the data in wDataColl ...

    DataColl= wDataColl;

Make sure to use Add to the existing collection instead (perhaps after using Clear()first if that is necessary)... If you still have problems after that please comment and i will try to help.

确保使用 Add to the existing collection 代替(Clear()如果有必要,可以先使用之后)...如果之后仍然有问题,请发表评论,我会尽力提供帮助。

Also, try to avoid using the Refresh()as it rebuilds the entire view and is unnecessarily expensive. If you do sorting, adding, removing etc. the correct way use of Refresh() isn't needed.

此外,尽量避免使用 ,Refresh()因为它会重建整个视图并且不必要地昂贵。如果您进行排序、添加、删除等操作,则不需要使用 Refresh() 的正确方法。