KeiStory

WPF CollectionView 에 필터 적용하기

 

CollectionView 는 필터를 적용하는 방법을 알아봅니다.

 

bool 값을 반환하는 메서드를 만들어 Filter 에 적용시키면됩니다.

bool 값을 반환하는 메서드를 아래 처럼 정의하고

이렌,ㄴ * "K" 로 시작하는 값만 필터링하는 방법입니다.

bool NameFilter(object obj)
{
    return (obj as Person).Name.StartsWith
    (
        "K",
        StringComparison.CurrentCultureIgnoreCase
    );
}

CollectionView 의 Filter = NameFilter; 로 적용하면 됩니다.

 

아래는 예시 코드입니다.

 Person.cs

using System.ComponentModel;
 
namespace WpfApp
{
    public class Person : INotifyPropertyChanged
    {
        /// <summary>
        /// 속성변경 이벤트입니다.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
 
        /// <summary>
        /// 이름입니다.
        /// </summary>
        string name = "";
 
        /// <summary>
        /// 별명입니다.
        /// </summary>
        string nickName = "";
 
        /// <summary>
        /// 이름입니다.
        /// </summary>
        public string Name
        {
            set
            {
                this.name = value;
                OnPropertyChanged(nameof(Name));
            }
            get { return name; }
        }
 
        /// <summary>
        /// 별명입니다.
        /// </summary>
        public string NickName
        {
            set
            {
                nickName = value;
                OnPropertyChanged(nameof(NickName));
            }
            get { return nickName; }
        }
 
        /// <summary>
        /// 속성 값이 변경될 때 발생합니다.
        /// </summary>
        /// <param name="propertyName"></param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

MainWindow.xaml

<Window x:Class="WpfApp3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="400">
    <StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="10">
            <TextBox Name="searchTextBox" Text="" Width="200" VerticalContentAlignment="Center"/>
            <Button Name="searchButton" Content="Search" Padding="5" Margin="5" Click="searchButton_Click"/>
        </StackPanel>
        <TextBox
            Margin="12" Height="50" VerticalContentAlignment="Center"
            Text="{Binding Name,
                   Mode=TwoWay,
                   UpdateSourceTrigger=PropertyChanged}" />
        <TextBox
            Margin="12" Height="50" VerticalContentAlignment="Center"
            Text="{Binding NickName,
                   Mode=TwoWay,
                   UpdateSourceTrigger=PropertyChanged}" />
        
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Name="prevButton" Content="Prev" Padding="10" Margin="10" Click="prevButton_Click"/>
            <Button Name="nextButton" Content="Next" Padding="10" Margin="10" Click="nextButton_Click"/>
        </StackPanel>
    </StackPanel>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Data;
 
namespace WpfApp3
{
    public partial class MainWindow : Window
    {
        /// <summary>
        /// 데이터 collectionView 입니다.
        /// </summary>
        ICollectionView collectionView;
 
        public MainWindow()
        {
            InitializeComponent();
 
            ObservableCollection<Person> datas = new ObservableCollection<Person>();
 
            datas.Add(new Person() { Name = "Kang",  NickName = "Super" });
            datas.Add(new Person() { Name = "An",    NickName = "Father" });
            datas.Add(new Person() { Name = "Jang",  NickName = "Marvel" });
            datas.Add(new Person() { Name = "Joo",   NickName = "Mother" });
            datas.Add(new Person() { Name = "Kim",   NickName = "DC" });
 
            this.collectionView = CollectionViewSource.GetDefaultView(datas);
            this.collectionView.Filter = NameFilter;
            this.collectionView.CurrentChanged += CollectionView_CurrentChanged; ;
 
            this.collectionView.SortDescriptions.Add(new SortDescription(nameof(Person.Name), ListSortDirection.Ascending));
 
            this.DataContext = this.collectionView;
 
            // 처음값으로 이동시킵니다.
            this.collectionView.MoveCurrentToFirst();
        }
 
        /// <summary>
        /// 이전 값으로 이동하는 버튼 클릭이벤트입니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void prevButton_Click(object sender, RoutedEventArgs e)
        {
            this.collectionView.MoveCurrentToPrevious();
        }
 
        /// <summary>
        /// 다음 값으로 이동하는 버튼 클릭이벤트입니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nextButton_Click(object sender, RoutedEventArgs e)
        {
            this.collectionView.MoveCurrentToNext();
        }
 
        /// <summary>
        /// CollectionView 현재값이 변경되었을때 발생되는 이벤트입니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void CollectionView_CurrentChanged(object sender, EventArgs e)
        {
            // 이전/다음 항목 존재여부에 따라 이전/다음 버튼을 활성화하거나 비활성화 합니다.
            this.prevButton.IsEnabled = this.collectionView.CurrentPosition > 0;
            this.nextButton.IsEnabled = this.collectionView.CurrentPosition < this.collectionView.Cast<object>().Count() - 1;
        }
 
        /// <summary>
        /// Search 버튼 클릭이벤트입니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void searchButton_Click(object sender, RoutedEventArgs e)
        {
            // Refresh 하여 필터 적용된 내용이 보이도록합니다.
            this.collectionView.Refresh();
        }
 
        /// <summary>
        /// 이름 기준 필터입니다.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        bool NameFilter(object obj)
        {
            return (obj as Person).Name.StartsWith
            (
                this.searchTextBox.Text,
                StringComparison.CurrentCultureIgnoreCase
            );
        }
    }
}

결과

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band