Filter BindingSource when DataSource is a BindingList
Asked Answered
L

2

4

I have read from a excel sheet and wrote this for a BindingList, in Form_Load() this is set to a DataSource as BindingSource:

bd = new BindingSource(); //instance of BindingSource
bd.DataSource = ExcelOPS.LerExcel(); //LerExcel() method return a BindingList<T>

gvFiltro.DataSource = bd; //set a DataGridView named gvFiltro DataSource property
bindNav.BindingSource = bd; //set a BindingNavigator source

This works fine! I intend to create a combobox as a filter for this DataGridView gvFiltro, so in the SelectedIndexChanged event of combobox, I try this:

this.gvFiltro.DataSource = null;
bd.Filter = string.Format("TAG_FAZENDA like '%{0}%'", cbTagFaz.Text);
gvFiltro.DataSource = bd;
gvFiltro.Update();
gvFiltro.Refresh();

bindNav.BindingSource = bd;
bindNav.Update();
bindNav.Refresh();

But the DataGridView doesn't change. did I miss something?

Lorrainelorrayne answered 22/2, 2016 at 17:45 Comment(2)
If the datagrid is in another container control, you may need to refresh that control as well.Mattah
Need I refresh the form?Profession
P
6

You can not use Filter property to filter a BindingSource which it's DataSource is set to a BindingList<T>.

Only underlying lists that implement the IBindingListView interface support filtering.

You can filter the BindingList<T> using Linq:

var filteredBindingList= new BindingList<T>(bindingList.Where(x=>some criteria).ToList());

Then you can use filtered binding list as data source.

Practicable answered 22/2, 2016 at 19:53 Comment(7)
@Franklin The only way for a BindingSource.Filter to actually effect your source is if the base source collection implements IBindingListView as discussed here. Otherwise this solution is your answer.Fann
@Reza Aghaei A ListBox with DataSource = filteredBindingList is not updated when some elements are added to bindingList. bindingList.ResetBindings() and filteredBindingList.ResetBindings() do not help. Is there any way to make a ListBox with a dynamically filtered data source? Thank you in advance,Gracegraceful
@Gracegraceful One solution is listening to ListChanged event of the binding list and set the data source of the listbox again.Practicable
It's worth mentioning that using this solution (ToList()) with LINQ doesn't filter the list but creates a new list with the filter condition, and therefore has performance / memory impacts which needs to be considered according to the number of times such functionality is invoked.Trillbee
This creates a new BindingList. When you add a new item to the original list, the filteredBindingList won't be able to see.Sorcery
This does not really work, as the list is no longer really bound to the original collection.Plasticizer
@Plasticizer Of course it doesn't work as you expected, because as it's already mentioned in the answer, only underlying lists that implement the IBindingListView interface support filtering. If you want that, you need to implement that interface yourself.Practicable
D
0

You may try it:

    bd.resetBindings(false)

Good luck

UPDATE

I would try something like this:

    bd.Filter = string.Format("TAG_FAZENDA like '%{0}%'", cbTagFaz.Text);
    gvFiltro.resetbindings(false)
    gvFiltro.Update();

    bindNav.resetbindings(false)
    bindNav.Update();

Just this.

Diazomethane answered 22/2, 2016 at 17:57 Comment(5)
I don't find this in methods list for private System.Windows.Forms.DataGridView gvFiltro;Profession
Yes, I'm sorry - my custom DatagridView has it. See the updated info above.Diazomethane
I tried this too, but don't works.Is this filter expression correct? The column name is TAG_FAZENDA , I believe this is correct. The DataGridView return all rows and not the filtered rows.Profession
Did you confirmed (in DEBUG MODE) if the Filter parameter is correctly presented? Set a breakpoint just after this line and check the filter syntax.Diazomethane
This ResetBindings is present only in BindingSource class. Thanks for your time, unfortunately don't work.Profession

© 2022 - 2024 — McMap. All rights reserved.