One of the most common way of searching in ListBox is to type text in TextBox and filter the ListBox items. In this article we will see how we can do this in Windows Phone application.
As you can see in above image, we have a TextBox where user can type, and a ListBox which get filtered based on text entered.
XAML Code
XAML Code
<
phone:PhoneApplicationPage
x:Class
=
"PhoneApp1.MainPage"
xmlns:phone
=
"clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell
=
"clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
mc:Ignorable
=
"d"
d:DesignWidth
=
"480"
d:DesignHeight
=
"768"
FontFamily
=
"{StaticResource PhoneFontFamilyNormal}"
FontSize
=
"{StaticResource PhoneFontSizeNormal}"
Foreground
=
"{StaticResource PhoneForegroundBrush}"
SupportedOrientations
=
"Portrait"
Orientation
=
"Portrait"
shell:SystemTray.IsVisible
=
"True"
>
<!--LayoutRoot is the root grid where all page content is placed-->
<
Grid
x:Name
=
"LayoutRoot"
Background
=
"Transparent"
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"*"
/>
</
Grid.RowDefinitions
>
<!--TitlePanel contains the name of the application and page title-->
<
StackPanel
x:Name
=
"TitlePanel"
Grid.Row
=
"0"
Margin
=
"12"
>
<
TextBlock
x:Name
=
"ApplicationTitle"
TextAlignment
=
"Center"
Text
=
"SEARCHABLE LISTBOX"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
</
StackPanel
>
<!--ContentPanel - place additional content here-->
<
Grid
x:Name
=
"ContentPanel"
Grid.Row
=
"1"
Margin
=
"12,0,12,0"
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"Auto"
/>
<
RowDefinition
Height
=
"*"
/>
</
Grid.RowDefinitions
>
<
TextBox
Grid.Row
=
"0"
Name
=
"txtSearchText"
/>
<
ListBox
Grid.Row
=
"1"
Background
=
"LightGray"
Name
=
"lstData"
Margin
=
"12,0"
/>
</
Grid
>
</
Grid
>
</
phone:PhoneApplicationPage
>
Windows Phone has a class called CollectionView which allows grouping, sorting, filtering and navigation in a data collection. To create a collection view for a collection that implements IEnumerable, we can create a CollectionViewSource
object, and add collection to the Source property. To filter the data based on TextBox text, we have to add event handler for Filter event.
In the above code, we are using "StartsWith" function to filter the Collection, and show the items which starts with text typed in TextBox. We can also use "Contains" function instead of "StartsWith" to show all the items which contains text typed in TextBox.
On TextChanged event on TextBox to reapply the filter we have to refresh the view using "CollectionViewSource.View.Refresh" function.
You can also refer following links to know more about CollectionViewSource
http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview.aspx
http://msdn.microsoft.com/en-us/library/ms752348.aspx
Private
Sub
BindListBox()
mTechnologiesCollectionSource.Source = mTechnologies
Dim
b
As
New
Binding
AddHandler
mTechnologiesCollectionSource.Filter,
AddressOf
mTechnologiesCollectionSource_Filter
b.Source = mTechnologiesCollectionSource
lstData.SetBinding(ListBox.ItemsSourceProperty, b)
End
Sub
Private
Sub
mTechnologiesCollectionSource_Filter(sender
As
Object
, e
As
FilterEventArgs)
Dim
str
As
String
= e.Item
If
String
.IsNullOrWhiteSpace(txtSearchText.Text) =
True
OrElse
str.ToUpperInvariant.StartsWith(txtSearchText.Text.ToUpperInvariant) =
True
Then
e.Accepted =
True
Else
e.Accepted =
False
End
If
End
Sub
In the above code, we are using "StartsWith" function to filter the Collection, and show the items which starts with text typed in TextBox. We can also use "Contains" function instead of "StartsWith" to show all the items which contains text typed in TextBox.
Private
Sub
mTechnologiesCollectionSource_Filter(sender
As
Object
, e
As
FilterEventArgs)
Dim
str
As
String
= e.Item
If
String
.IsNullOrWhiteSpace(txtSearchText.Text) =
True
OrElse
str.ToUpperInvariant.Contains(txtSearchText.Text.ToUpperInvariant) =
True
Then
e.Accepted =
True
Else
e.Accepted =
False
End
If
End
Sub
On TextChanged event on TextBox to reapply the filter we have to refresh the view using "CollectionViewSource.View.Refresh" function.
Imports
System.Collections.ObjectModel
Imports
System.Windows.Data
Partial
Public
Class
MainPage
Inherits
PhoneApplicationPage
Dim
mTechnologies
As
New
ObservableCollection(Of
String
)
Dim
mTechnologiesCollectionSource
As
New
CollectionViewSource
' Constructor
Public
Sub
New
()
InitializeComponent()
FillListBox()
End
Sub
Private
Sub
FillListBox()
mTechnologies.Add(
"HTML"
)
mTechnologies.Add(
"Silverlight"
)
mTechnologies.Add(
"Visual Basic"
)
mTechnologies.Add(
"Visual C#"
)
mTechnologies.Add(
"Visual F#"
)
mTechnologies.Add(
"Window Communication Foundation"
)
mTechnologies.Add(
"Window Presentation Foundation"
)
mTechnologies.Add(
"Window Phone"
)
mTechnologies.Add(
"XML"
)
mTechnologies.Add(
"XAML"
)
End
Sub
Private
Sub
MainPage_Loaded(sender
As
Object
, e
As
RoutedEventArgs)
Handles
Me
.Loaded
BindListBox()
End
Sub
Private
Sub
BindListBox()
mTechnologiesCollectionSource.Source = mTechnologies
Dim
b
As
New
Binding
AddHandler
mTechnologiesCollectionSource.Filter,
AddressOf
mTechnologiesCollectionSource_Filter
b.Source = mTechnologiesCollectionSource
lstData.SetBinding(ListBox.ItemsSourceProperty, b)
End
Sub
Private
Sub
mTechnologiesCollectionSource_Filter(sender
As
Object
, e
As
FilterEventArgs)
Dim
str
As
String
= e.Item
If
String
.IsNullOrWhiteSpace(txtSearchText.Text) =
True
OrElse
str.ToUpperInvariant.StartsWith(txtSearchText.Text.ToUpperInvariant) =
True
Then
e.Accepted =
True
Else
e.Accepted =
False
End
If
End
Sub
Private
Sub
txtSearchText_TextChanged(sender
As
Object
, e
As
TextChangedEventArgs)
Handles
txtSearchText.TextChanged
mTechnologiesCollectionSource.View.Refresh()
End
Sub
End
Class
You can also refer following links to know more about CollectionViewSource
http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview.aspx
http://msdn.microsoft.com/en-us/library/ms752348.aspx