How to Apply Multiple Filtering Criteria in a CustomObservableCollection?

fatih uyanık 160 Reputation points
2024-12-27T08:28:57.8266667+00:00

Hello

I am managing data in my WPF application using a CustomObservableCollection. I created a custom collection by inheriting from ObservableCollection in order to control any additional operations that might arise on the collection in the future. Now, on the UI side, I want to apply multiple filter criteria (e.g., if “Field1” contains something, if “Field2” starts with something, etc.) to the displayed data.

Should I handle these filtering operations using LINQ within the CustomObservableCollection, or would it be better to take advantage of the existing “filter” functionality in ObservableCollection (e.g., via CollectionViewSource)? Or is there an entirely different, more appropriate approach?

I would appreciate any suggestions or insights you might have.

Thanks.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,806 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,159 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Hongrui Yu-MSFT 3,645 Reputation points Microsoft Vendor
    2024-12-27T09:55:45.8533333+00:00

    Hi, @fatih uyanık. Welcome to Microsoft Q&A. 

    ObservableCollection is generally used for data display. In WPF, it is recommended to use CollectionViewSource to filter the data of ObservableCollection instead of using Linq.

    Difference:

    If you use LINQ to filter the data in ObservableCollection, you could only re-query the database if you need to use the data before ObservableCollection filtering in other places.

    If you use CollectionViewSource to filter the data, the view data will be filtered, and the data stored in ObservableCollection will not change. The WPF program always keeps an original version of the data. In addition, in WPF, the data in ObservableCollection is mostly used for display in the UI. Using CollectionViewSource, you could also use grouping, sorting and other operations. Finally, CollectionViewSource filtering could be added or cancelled at any time.More about CollectionViewSource.

    Simple Example: MainWindow.xaml

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="7*"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <DataGrid x:Name="MyDataGrid" CanUserAddRows="False" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Id" Binding="{Binding Id}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Name" Binding="{Binding Name}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Area" Binding="{Binding Area}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Population" Binding="{Binding Population}"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>
            <Button Grid.Row="1" Content="Add Filter/Remove Filter" Click="Button_Click" Width="200"></Button>
        </Grid>
    

    MainWindow.xaml.cs

        public partial class MainWindow : Window
        {
            public MainWindowViewModel viewModel;
            public bool EnableFilter = false;
            public ICollectionView collectionView;
            public MainWindow()
            {
                InitializeComponent();
                viewModel = new MainWindowViewModel();
                this.DataContext = viewModel;
                collectionView = CollectionViewSource.GetDefaultView(viewModel.cities);
                MyDataGrid.ItemsSource = collectionView;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                EnableFilter = !EnableFilter;
                if(EnableFilter)
                {
                    collectionView.Filter = viewModel.Filter;
                }
                else
                {
                    collectionView.Filter = null;
                }
                collectionView.Refresh();
            }
        }
    

    City.cs

        public class City
        {
            public int Id { get; set; }
            public string Name { get; set; }
    
            public string Area { get; set; }
    
            public int Population { get; set; }
        }
    

    CustomObservableCollection.cs

        public class CustomObservableCollection<T>:ObservableCollection<T>
        {
        }
    

    MainWindowViewModel.cs

        public class MainWindowViewModel
        {
            public CustomObservableCollection<City> cities = new CustomObservableCollection<City> { 
                new City() { Id = 1,Name="A_A",Area="A",Population=5 },
                new City() { Id = 2,Name="B_A",Area="B",Population=2 },
                new City() { Id = 3,Name="C_A",Area="C",Population=1 },
                new City() { Id = 4,Name="B_B",Area="B",Population=4 },
                new City() { Id = 5,Name="C_B",Area="C",Population=7 },
                new City() { Id = 6,Name="A_B",Area="A",Population=6 },
                new City() { Id = 7,Name="A_C",Area="A",Population=8 },
                new City() { Id = 8,Name="D_A",Area="D",Population=3 },
            };
    
            public bool Filter(object item)
            {
                if (item is City data)
                {
                    return data.Area=="A" && data.Population>5;
                }
                return false;
            }
        }
    

    In MainWindowViewModel.cs, you could see that you could write multiple filter conditions in Filter. And, in the example program above, you could add or cancel filters at any time.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.