BRDroid
BRDroid

Reputation: 4388

Filtering a xaml list box

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

Answers (2)

Krishna
Krishna

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

romerotg
romerotg

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

Related Questions