| |
|
Using the ListCollectionView Filter method in WPF with C#
|
| |
|
|
| |
| NOTE: This solution does not implement paging and requires
the retrieval of the entire result set. If your dataset is huge, I wouldn’t
go this route. Other options, LIKE %text%, FULL-TEXT search, Lucene.Net…and
many others… Check out another of my blogs
where I defer the retrieval using a Delayed Action.
|
| |
|
Again, if you look hard enough for something you can find it. I was tasked
with creating a filter on a dynamically created DataGrid in a WPF program
using C#. First, finding and understanding the ListCollectionVIew was a
challenge, and then came the implementation. Initial research resulted
in finding most examples using a strongly typed list to populate the
DataGrid and therefore searching the result set and repopulating the
DataGrid was just a few lines of code.
|
| |
|
The problem with strongly typing the data set is that your users are limited
to using and accessing only that object. For example, a system which presents
and captures only customer details. My requirements were to allow a user to
select any column from any table, build the query, populate a DataGrid and
then filter through the results. That was not a 3 or 4 liner and I wasn’t
able to find many examples of this. However, when I was able to pull it off,
it provided the user with an interface into the database that allowed them
to view and capture data in any way they wanted.
|
| |
|
NOTE: I had to hack a little to get the data loaded in a way that worked here.
When retrieved from a real database it would be in the correct format.
The ListCollectionVIew wants an IList.
|
| |
|
The first thing to do is create some variable to store the ListCollectionVIew
and the DataSet.
|
| |
ListCollectionView CollectionViewList;
DataTable DataTableFiltered;
|
| |
|
In the method where you load the data into your DataTable or GridView, load
the result set into the CollectionViewList too.
|
| |
CollectionViewList = new ListCollectionView(results);
|
| |
| The trigger for the filter is the TextChanged event of the filter
text box on the WPF window. I have created a Textbox_TextChanged() method.
The TextChanged() method calls the method ContainsIt() which checks each row
of the DataGrid for a matching value currently typed into the filter text
box. If true is returned from the ContainsIt() method, then the filter
entered into the textbox on the WPF window it applied to the
CollectionViewList. I.e. when applied, only the matching rows will exist
in the CollectionViewList object. |
| |
private void textBox1_TextChanged(object sender,
TextChangedEventArgs e)
{
if (textBox1.Text != "")
{
if (CollectionViewList.CanFilter)
{
CollectionViewList.Filter =
new Predicate<object>(ContainsIt);
FilterIt();
}
else
{
CollectionViewList.Filter = null;
}
}
else
{
CollectionViewList.Filter = null;
FilterIt();
}
}
|
| |
| The COntainsIt() method loops through each row in the
DataGrid to determine if the value entered into the TextBox exists in
the DataGrid row. If it does, then true is returned, if not, false.
|
| |
public bool ContainsIt(object value)
{
if (DataTableFiltered.Columns.Count > 1)
{
//There is more than 1 column in DataGrid
List<string> DataGridRowList = (List<string>)value;
foreach (object item in DataGridRowList)
{
if (item != null)
{
if(item.ToString()
.ToLower()
.Contains(textBox1.Text
.ToLower())) return true;
}
}
}
else
{
//There is a single column in the DataGrid
if (value.ToString().ToLower()
.Contains(textBox1.Text
.ToLower())) return true;
}
return false;
}
|
| |
| Once the data has been filtered out of the CollectionViewList
object, I then repopulate the DataTable with the newly filtered
CollectionViewList object. This repopulation happens in the FIlterIt()
method below. |
| |
public void FilterIt()
{
int count = 0;
DataTableFiltered.Clear();
dataGrid1.ItemsSource = null;
foreach (List row in CollectionViewList)
{
DataTableFiltered
.Rows
.Add(row[0], row[1], row[2], row[3], row[4]);
count++;
}
dataGrid1.ItemsSource = DataTableFiltered.DefaultView;
}
|
| |
| That’s it. Keep on coding and rockin!!! |
| |
| Download the source |
| |
|
|