2

我有一个DataGrid每隔几秒钟通过Thread. DataGrid需要提供列标题排序、分组和过滤。

我目前有一个DataGrid绑定到 aICollectionView的来源ICollectionView是一个ObservableCollection. 从我在其他线程上阅读的内容来看,这似乎是一个好方法。

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

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

编辑这里有一些代码......

查看 (XAML)

<DataGrid ItemsSource="{Binding CollectionView, Source={StaticResource 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");
    }
}

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

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;
    }
}
4

2 回答 2

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

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

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

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

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

当你说:

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

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

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

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

您正在将 itemsource 绑定到 CollectionViewSource,您应该将 datacontext 绑定到它:

例子:

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

在页面中:

<Grid DataContext="{StaticResource myViewSource}">

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

或类似的规定

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

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

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

还:

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

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

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

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

于 2013-04-24T20:09:03.310 回答
0

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

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

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

    DataColl= wDataColl;

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

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

于 2013-04-24T21:25:15.543 回答