Reputation: 4388
Hi I have a list box with some customer names, I want to filter the list based on the text entered in the TextBox. After researching a bit I heard that we can use CollectionViewSourse and ICollectionView but did not get a stage where I could get it working.
Could you please suggest on how to achieve this.
Your help is much appreciated.
XAML
<TextBox x:Name="txtSearch"/>
<ListBox x:Name="lbCustomers">
XAML.cs
List<string> customerList;
public MainPage()
{
this.InitializeComponent();
customerList = new List<string>();
customerList.Add("Andrew");
customerList.Add("bravo");
customerList.Add("Carol");
customerList.Add("Dela");
customerList.Add("Eva");
customerList.Add("family");
customerList.Add("George");
customerList.Add("Health");
customerList.Add("Illa");
customerList.Add("Jack");
customerList.Add("Andrew");
lbCustomers.ItemsSource = customerList;
CollectionViewSource collectionViewSource = new CollectionViewSource();
collectionViewSource.Source = customerList;
ICollectionView collectionView = collectionViewSource.View;
}
Edit: I can not access 'CollectionViewSource.GetDefaultView' and 'view.Filter'. I get an error : 'collectionviewsource does not contain a definition for getdefaultview'
When I looked into the definition i did not find the 'GetDefaultView' and 'Filter dependency properties'
public sealed class CollectionViewSource : DependencyObject, ICollectionViewSource
{
public CollectionViewSource();
public static DependencyProperty IsSourceGroupedProperty { get; }
public static DependencyProperty ItemsPathProperty { get; }
public static DependencyProperty SourceProperty { get; }
public static DependencyProperty ViewProperty { get; }
public System.Boolean IsSourceGrouped { get; set; }
public PropertyPath ItemsPath { get; set; }
public System.Object Source { get; set; }
public ICollectionView View { get; }
}
Upvotes: 1
Views: 836
Reputation: 1996
I would advice you to read about data binding and how it use it to bind listboxes and textboxes and manage your collections in your viewmodels.
But to fix your problem as it is.
Define your IcollectionView at a global level just like customerList and in your main change your code to
CollectionViewSource collectionViewSource = new CollectionViewSource();
collectionViewSource.Source = customerList;
collectionView = collectionViewSource.View;
collectionView.Filter = collectionFilter;
lbCustomers.ItemsSource = collectionView;
and add these 2 additional methods
private bool collectionFilter(object obj)
{
if (string.IsNullOrWhiteSpace(txtSearch.Text))
return true;
string name = obj.ToString();
return name.Contains(txtSearch.Text);
}
private void TxtSearch_OnTextChanged(object sender, TextChangedEventArgs e)
{
collectionView.Refresh();
}
change textbox to
<TextBox x:Name="txtSearch" TextChanged="TxtSearch_OnTextChanged"/>
These should be self explanatory changes but if you need any help i am happy to explain
The filter method is where you define your logic of filtering the listbox items on display
Upvotes: 1
Reputation: 464
Try getting the default collection view for your collection. Every time your txtSearch changes you have to change the filter.
ICollectionView view = CollectionViewSource.GetDefaultView(customerList);
view.Filter = obj =>
{
string item = obj as string;
return (item.ToLower().Contains(YourFilter));
};
Upvotes: 1