1

I want to use deferred execution to my advantage for updating changing data in a data grid view when the view is filtered. Currently I have an array of rows which can be filtered and the filtered data can then be searched. I use linq queries to filter the data and search the data. I've summarized how I do this below.

IEnumerable<SomeDataRowType> m_mainData =
  (select from someDataContext
   new SomeDataRowType {
     properties...
   }).ToArray();

IEnumerable<SomeDataRowType> m_filteredData =
  m_mainData.Where(r => r.SomeProperty == someValue);

IEnumerable<SomeDataRowType> m_searchedData =
  m_filteredData.Where(r => r.SomeProperty.Contains(someSearchTerm));

myDataGridView.DataSource = new SortableBindingList<SomeDataRowType>(m_searchedData.ToArray());

Now this works great if the m_mainData data set doesn't change. I can clear the search query and drop back to the filter query, or drop them both, or just apply the search query. Unfortunately if the m_mainData set DOES change then m_filteredData and m_searchedData filter execute on the old m_mainData data set instead of the new updated one. I sort of understand why this is, but I don't know what my options are to work around this.

I apologize if any of this is unclear. Thanks for the help!

MarkSchad
  • 9
  • 2
  • What is `SortableBindingList` here, and how exactly does it operate? AFAIK that is not a BCL class. But the implementation matters: if it basically populates a list or array internally (which would make sense - binding-list is usually heavily `IList`-focused), then there may be no way of solving this, except to rebuild it when needed. – Marc Gravell Aug 14 '13 at 07:04
  • Simply a custom class that allows the data grid view to be sorted by multiple columns quite easily. I build a new SortableBindingList whenever the filter or search changes. – MarkSchad Aug 14 '13 at 07:18

1 Answers1

1

To make m_mainData, m_filteredData and m_searchedData deferred, simply remove the ToArray() in the top statement:

IEnumerable<SomeDataRowType> m_mainData =
  (select from someDataContext
   new SomeDataRowType {
     properties...
   });

Note, however, that I strongly suspect that your SortableBindingList<T> internally populates a list of some form: data-binding in the winforms/wpf/etc model is heavily IList-based, and SortableBindingList<T> suggests a custom class related to BindingList<T>. If this is the case, the binding-list will never be deferred - so you will probably need no simply rebind as necessary. Or even better: just maintain the binding-list directly - the entire point of a binding-list is that it propagates change notifications.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • In this case I'm only using the SortableBindingList, a custom class derived from BindingList to allow the data grid view to sort multiple columns more easily. – MarkSchad Aug 14 '13 at 07:16
  • @user2213625 You have 2 options: re-bind the list (of course without calling `ToArray()`) or perform the filter directly on your `List`. That's what I can understand in this answer. – King King Aug 14 '13 at 07:18
  • @user2213625 right; and `BindingList` is `IList`-based: it *doesn't work* against `IEnumerable`. Presumably you are doing `ToList()` or similar in the constructor. Basically, that class *is not intended* to be used with deferred execution. – Marc Gravell Aug 14 '13 at 07:18
  • My apologies, I've updated the original post to clarify, I call ToArray() when creating the BindingList. – MarkSchad Aug 15 '13 at 06:38