快速查找datagridview中的行选择状态

时间:2012-06-26 20:33:32

标签: .net winforms datagridview datatable

我有一个约有1/2万条记录的绑定数据网格视图,可以按任何列排序。在GUI中,用户可以选择任意数量的行(有时所有行都使用CTRL + A)。从另一个来源,我得到一个大的记录ID列表(最多1000个),并需要找出哪些ID对应于选定的行。我尝试了很多方法,其中没有一种方法表现得足够快。例如:

循环选定的行集合并在ID列表中查找匹配是不可能的,因为SelectedRows计数可以是大约1/2百万的数量。

我还尝试循环访问ID列表(通常大约为1000),并为每个ID执行BindingSource.Find(“Id”,Value),它为每个ID提供行索引,然后我可以检查是否选中了行。如果网格按ID排序,这可以正常工作,但如果不是,则Find()的性能太差,无法调用1000次。

简而言之,在需要行对象ID的情况下,我需要一种快速的方法来查找最多1000行的Row.Selected状态。似乎DataGridView或DataBinding应该能够处理这个问题,但它并不明显。提前谢谢!

1 个答案:

答案 0 :(得分:1)

我会尝试以下方法:

  1. 如果可能,请对DataGridView的ItemsSource使用ObservableCollection。
  2. 将行的Selected属性上的绑定添加到ObservableCollection中包含的基础项目。
  3. 使用CollectionViewSource和Filter
  4. 这是一个非常相似的例子(尽管我怀疑它的表现会非常好):

    private ICollectionView _CarListView { get; set; }
    private ObservableCollection<Car> _CarList;
    public ObservableCollection CarList
    {
        get
        {
            if (_CarList == null)
            {
                //Code to build the list
    
                //For the car filtering
                this._CarListView = CollectionViewSource.GetDefaultView(_CarList);
                this._CarListView.Filter = CarFilter;
            }
            return _CarList;
        }
    }
    
    private bool CarFilter(object item)
    {
        Car car = item as Car;
    
        if(car.Name.Contains(FilterText))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    

    在您的情况下,我只是调整CarFilter(实际上是Predicate<T>),以便您可以查找绑定到DataGridViewRow中Selected属性的属性。例如,您可以在ObservableCollection中包含的对象类型上创建一个IsSelected布尔值,并返回该项为true的位置。获得筛选后的列表结果后,请运行您提到的较小的ID列表(大约1000个元素),并查看ID匹配的位置。我会尝试对两个集合使用LINQ查询来执行该操作,该操作应该尽可能快。

    如果所有其他方法都失败了,您可以回到原来的循环技术并尝试使用并行库来执行Parallel.ForEach,它将利用您的多核CPU更快地执行操作。虽然,我不会蛮力。看起来您必须进行一次传递以累积大型集合中的所选项目,然后在较小的集合中查找每个所选项目。