Andrew Davies created an excellent little class on sourceforge called BindingListView<T>
which essentially allows you to bind a collection to a DataGridView
while supporting sorting and filtering. Binding a DataGridView
to a normal List<T>
does not support sorting and filtering, as the proper interfaces are not implemented by List<T>
.
The class works great and has solved my UI problems. However, it'd be awesome if I could iterate through the collection using LINQ, but I'm just not sure how to set it up to do so. Source code can be downloaded here. Can anyone help me out?
Because the BindingListView<T>
project uses .NET Framework v2.0 and predates LINQ, it doesn't expose an IEnumerable<T>
for you to query on. Since it does implement non-generic IEnumerable
and non-generic IList
, you can use Enumerable.Cast<TResult>
to convert the collection into a form suitable for use with LINQ. However, this approach isn't that helpful because the IEnumerable
that AggregateBindingListView<T>
returns is an internal data structure with type KeyValuePair<ListItemPair<T>, int>
.
To upgrade this project for convenient use with LINQ, the simplest approach might be to implement IEnumerable<T>
on AggregateBindingListView<T>
. First add it to the declaration of the class:
public class AggregateBindingListView<T> : Component, IBindingListView, IList, IRaiseItemChangedEvents, ICancelAddNew, ITypedList, IEnumerable<T>
and then implement it at the end of the class definition:
#region IEnumerable<T> Members
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
for (int i = 0; i < _sourceIndices.Count; i++)
yield return _sourceIndices[i].Key.Item.Object;
}
#endregion
and now you can use LINQ directly on a BindingListView<T>
instance like this:
// Create a view of the items
itemsView = new BindingListView<Item>(feed.Items);
var descriptions = itemsView.Select(t => t.Description);
Remember to upgrade all the projects from .NET Framework v2.0 to .NET Framework 4 Client Profile and add using System.Linq;
in order for this to work with your current project.
Ok this is what I got: Here is my extension method :
public static class BindingViewListExtensions
{
public static void Where<T>(this BindingListView<T> list, Func<T, bool> function)
{
// I am not sure I like this, but we know it is a List<T>
var lists = list.DataSource as List<T>;
foreach (var item in lists.Where<T>(function))
{
Console.WriteLine("I got item {0}", item);
}
}
}
And then I used it like :
List<string> source = new List<string>() { "One", "Two", "Thre" };
BindingListView<string> binding = new BindingListView<string>(source);
binding.Where<string>(xx => xx == "One");
I guess where in the extension method could return the found item.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With