Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter items of a ListBox based on the text of a TextBox using only XAML in WPF

Tags:

c#

.net

wpf

xaml

I currently have a ListBox binded to a collection of items. As the collection is big we want to filter the items being shown based on the text entered on a TextBox.

What I'm asking is if this is possible to implement using only XAML, I don't want to modify the collection of items, I would like to modify the Visibility of each of the items based on the filter.

Hope its clear,

thanks!

like image 595
Ignacio Soler Garcia Avatar asked Aug 17 '11 13:08

Ignacio Soler Garcia


3 Answers

You can use the CollectionViewSource to apply filtering, another example can be found here and here.

like image 59
CodeNaked Avatar answered Nov 09 '22 06:11

CodeNaked


Like CodeNaked and devdigital told you CollectionViewSource/CollectionView/ICollectionView are the keys to your goal

It's a MVVM patter but this is a View only related problem so I don't want this code at the ViewModel.

thats not the right way because the View only shows what she get´s but shouldn´t modifi so it should/must be your ViewModel who handel changes

so now some code snips:

    public class myVM
    {
        public CollectionViewSource CollViewSource { get; set; }
        public string SearchFilter
        {
            get;
            set
            {
              if(!string.IsNullOrEmpty(SearchFilter))
                 AddFilter();

                CollViewSource.View.Refresh(); // important to refresh your View
            }
        }
        public myVM(YourCollection)
        {
            CollViewSource = new CollectionViewSource();//onload of your VM class
            CollViewSource.Source = YourCollection;//after ini YourCollection
        }
    }

Xaml Snip:

    <StackPanel>
        <TextBox Height="23" HorizontalAlignment="Left"  Name="tB" VerticalAlignment="Top" 
                 Width="120" Text="{Binding SearchFilter,UpdateSourceTrigger=PropertyChanged}" />
        <DataGrid Name="testgrid" ItemsSource="{Binding CollViewSource.View}"/>
    </StackPanel>

Edit i forgot the Filter

private void AddFilter()
{
    CollViewSource.Filter -= new FilterEventHandler(Filter);
    CollViewSource.Filter += new FilterEventHandler(Filter);  

}

private void Filter(object sender, FilterEventArgs e)
{
    // see Notes on Filter Methods:
    var src = e.Item as YourCollectionItemTyp;
    if (src == null)
        e.Accepted = false;
    else if ( src.FirstName !=null && !src.FirstName.Contains(SearchFilter))// here is FirstName a Property in my YourCollectionItem
        e.Accepted = false;
}
like image 25
Karl_Schuhmann Avatar answered Nov 09 '22 08:11

Karl_Schuhmann


You can do this with a CollectionViewSource. You wouldn't want to do this completely in XAML, as it would be much easier to test this if the filtering code is in your view model (assuming an MVVM design pattern).

like image 34
devdigital Avatar answered Nov 09 '22 08:11

devdigital