0

I have a Grid which has two viewing modes : All Items, or only items with PropertyX = A. Views switch based on a CheckBox toggle.

I have one copy of the collection in my object model layer that is frequently updated, and I'd like to ideally apply the filter to it at the data layer. Is there a way to apply a filter to this collection for binding purposes, without creating a second copy of the collection or applying a UI filter?

I think what I am looking for is something like a CollectionViewSource from WPF, but that doesn't appear to be available in WinForms.

From what I can tell, my options are :

  1. Some data-layer construct that can apply a filter to the binding source that can be modified from the data layer, like a CollectionViewSource

  2. Create a second copy of my collection, and maintain it in sync whenever the first collection gets updated. Not ideal because of the frequency of items added, removed, and modified.

  3. Use a UI filter... not ideal because there is a lot of UI-specific things done with filters already, so this solution would mix controlling the filter between UI and Data layer, and gets messy.

  4. Something else?

Is there something that acts like a CollectionViewSource in WinForms so I can use option #1? Or if not, what is the standard way of handling this kind of scenario in WinForms?

It should be noted that PropertyX never changes its value. If it is A, it is always A. So that helps.


Here's what I've been trying to do so far :

public IEnumerable<MyClass> DisplayItems
{
    get
    {
        if (SomeFlagIsChecked)
            return _allItems;

        return _allItems.Where(p => p.PropertyX == A);
    }
}

My issue here is setting the DataSource to IEnumerable doesn't seem to be working. I'm not sure if that's a Winforms thing, a .Net 3.5 thing, or a limitation of the 3rd party control I am using (DevExpress GridView).

I don't want to cast it to a .ToList() because the collections are anywhere from a few hundred to a few thousand records, and get refreshed every couple of minutes. So ideally I'd like to avoid creating new objects every time I need a refresh.

Rachel
  • 130,264
  • 66
  • 304
  • 490
  • If the filter triggers with a `CheckBox` and only shows or hides some records without a new request to the server (database/web), so the filter should be applied on UI layer. You should have a `List` containing all items and another one containing filtered items which is created using linq. It doesn't introduce performance issues, because the second list contains only pointers to items of the first list, it doesn't contain duplicates of items. – Reza Aghaei Sep 28 '16 at 14:31
  • If you should send a new request to server (web/database) and apply the filter on server to get filtered items, so obviously the filter is server-side and it can be done by adding a bool parameter or a search model to the method which returns data, then apply the filter in method. You need to call this method on change on the `CheckBox` or when the user requested, for example by clicking a `Search` button. – Reza Aghaei Sep 28 '16 at 14:35
  • @RezaAghaei I am currently attempting some kind of solution like that. The server is used to retrieve new/updated/deleted items every couple minutes. The collection is maintained on the data layer of the application, and I am trying to get the grid to bind using an IEnumerable via Linq. I do not want to put the filter in the UI layer because there is another whole case of logic for how the filters are maintained, and I'd like to keep that separate from this specific datasource filter. – Rachel Sep 28 '16 at 14:58
  • Maybe I didn't get the situation. But I think a filter is a state which should be maintained in client-side. Then you can use the filter for your next requests. For example paging a filtered result, or sorting a filtered result. The mechanism of storing the filter in client side doesn't change the way you work with filter parameters at server side and vice versa. – Reza Aghaei Sep 28 '16 at 15:03
  • @RezaAghaei Yes, the filter should be maintained client-side, but I want it in the data-layer of my application, not in the actual UI grid displaying the data. Unfortunately I am using a 3rd party control library, and a custom collection, so it is making my life difficult trying to figure out what I can and can't bind to. I've already determined I can't bind to an IEnumerable, and I don't want to keep creating new lists every few minutes when data refreshes. My biggest concern is performance because the collections are a few hundred to few thousand records, and refresh every couple minutes. – Rachel Sep 28 '16 at 15:05
  • I don't know if it may help or not but, take a look at this asp.net mvc [answer](http://stackoverflow.com/a/33154580/3110834). I use the same solution in Windows Forms Applications. Then I just add the result to `BindingList` and show in a grid. When the user changes the filter criteria, I send a new request to the method which accepts the filter and get the filtered result again. – Reza Aghaei Sep 28 '16 at 15:09
  • @RezaAghaei Thanks, I will take a look. I think right now I'm just feeling frustrated with the tech stack I'm working on, and am probably just missing something obvious. I'll probably just end up using `.ToList()` and be done with it... – Rachel Sep 28 '16 at 15:17

0 Answers0