Thursday, March 19, 2009

Filter using Predicate (WPF)

In WPF, XAML has changed the traditional way of creating and validation the form fields. For example, what if we want to display few of the items in a listview? And what if we want to give user an option to view the items with in the listview?

Without WPF, we will create the loop through all the items and will hide/show the items accordingly. But with WPF, we can do it very easily. I will explain in the following example.

Create a class SampleClass with Two Properties, Name(of string type) and Visible(of boolean type)

Create an ObservableCollection of type SampleClass in your Xaml.cs.

Code : ObservableCollection< SampleClass > collection = new ObservableCollection ()

Add few Items :

collection.Add(new SampleClass("Vikas", true));
collection.Add(new SampleClass("Sonia", true));
collection.Add(new SampleClass("Viman", False));
collection.Add(new SampleClass("Krishna", False));

Add the collection to our listview

myListView.DataContext = collection.

Now, for having a smooth access on filtering, sorting etc features, we will need to get the ICollectionView(Click to know more about ICollectionView) object out of out observable collection.

ICollectionView view = CollectionViewSource.GetDefaultView(collection);

now, to apply the filter we can use the following line anywhere in the code where in we want to put a filter on:

view.Filter = delegate(object item)
{
SampleClass sItem = item as SampleClass;
bool retValue = false;

if(sItem!=null)
{
retValue = sItem.Visible;
}

return retValue;
}

We can do the above step by using a new method with the predicate as well.

private bool GetVisibleState(object item)
{
SampleClass sItem = item as SampleClass;
bool retValue = false;

if(sItem!=null)
{
retValue = sItem.Visible;
}

return retValue;
}

And add the filter like following :

view.Filter = new Predicate< object >(GetVisibleState);

The above code will show the items in which the Visible property is set to true.

The code in VB.net is as follows :


Dim view As ICollectionView
Dim collection As ObservableCollection(Of SampleClass) = New ObservableCollection(Of SampleClass)

collection.Add(New SampleClass("Vikas", True))
collection.Add(New SampleClass("Sonia", True))
collection.Add(New SampleClass("Viman", False))
collection.Add(New SampleClass("Krishna", False))

myListView.DataContext = collection


view = CollectionViewSource.GetDefaultView(collection)
view.Filter = New Predicate(Of Object)(AddressOf FilterItems)



Private Function FilterItems(ByVal param As Object) As Boolean

Dim proxy As SampleClass
Dim Name As String
Dim retValue As Boolean

Name = combovalue ' (some arbit value, which you want to use as a filter. Example, the if you want to filter the value if the name is vikas, then say name = "Vikas")

proxy = TryCast(param, SampleClass)
retValue = proxy.Show

Return retValue

End Function


Public Class SampleClass
Private _name As String
Private _show As Boolean

Public Sub New(ByVal name As String, ByVal show As Boolean)
_name = name
_show = show
End Sub

Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property

Public Property Show() As Boolean
Get
Return _show
End Get
Set(ByVal value As Boolean)
_show = value
End Set
End Property
End Class

3 comments:

Vidhu said...

Nice Article :)

Anonymous said...

Thank you :)

Anonymous said...

Works perfectly! Clean and simple!