DataFilter for WinForms
カスタムフィルタ
DataFilter > カスタムフィルタ

The DataFilter control allows you to create custom filters which can replace the default filter editors at runtime. It provides CustomFilter class which needs to be inherited for defining a custom filter. Inheriting the CustomFilter class provides access to its properties and methods which can further be used to create a custom filter.

Following example shows how you can create and add custom filter to the DataFilter control. It demonstrates how you can filter the car models using the MultiSelect control as a part of the DataFilter control UI.

  1. Define a custom filter by creating a new class which inherits the CustomFilter class. In the class constructor, use Control property of the CustomFilter class to specify the custom control that you want to use to perform filtering in the DataFilter control. For example, the following code is used for defining a custom filter, ModelFilter, to filter the data using the MultiSelect control as a filter within the DataFilter control.
    'CustomFilterクラスを継承してカスタムフィルタを定義します
    Public Class ModelFilter
        Inherits CustomFilter
    
       Private _multiSelect As C1MultiSelect
    
       'MultiSelectコントロールの設定をカスタマイズします
        Public ReadOnly Property MultiSelect As C1MultiSelect
            Get
                Return _multiSelect
            End Get
        End Property
    
            Public Sub New()
                    'カスタムフィルタを表すコントロールを「Control」プロパティに設定します
                    Control = (_multiSelect, New C1MultiSelect() With {
                    .Height = 50,
                    .Placeholder = "Model of car",
                    .AutoCompleteMode = AutoCompleteMode.SuggestAppend
                            })
            _multiSelect.SelectionChanged += MultiSelect_SelectionChanged
    
    End Sub
    End Class
    
    //CustomFilterクラスを継承してカスタムフィルタを定義します
    public class ModelFilter : CustomFilter
    {
            private C1MultiSelect _multiSelect;
    
        //MultiSelectコントロールの設定をカスタマイズします
        public C1MultiSelect MultiSelect { get { return _multiSelect; } }
    
        public ModelFilter()
        {
            //カスタムフィルタを表すコントロールを「Control」プロパティに設定します
            Control = _multiSelect = new C1MultiSelect() { Height = 50,
                Placeholder = "Model of car", AutoCompleteMode =
                AutoCompleteMode.SuggestAppend };
            _multiSelect.SelectionChanged += MultiSelect_SelectionChanged;
        }
    }
    
  2. Bind the MultiSelect control with data. In this example, we are binding the control with data using the SetTagList method.
    'MultiSelectコントロールをデータと連結します
    _multiSelect.BindingInfo.DataSource = tagSource
    _multiSelect.BindingInfo.DisplayMemberPath = PropertyName
    End Sub
    
    public void SetTagList(object tagSource)
    {
        //MultiSelectコントロールをデータと連結します
        _multiSelect.BindingInfo.DataSource = tagSource;
        _multiSelect.BindingInfo.DisplayMemberPath = PropertyName;
    }
    
  3. Raise the ValueChanged event of the CustomFilter class in the SelectionChanged event of the MultiSelect control which gets fired when the user selects values from the MultiSelect control. This notifies the DataFilter control about the change in filter values.
    Private Sub MultiSelect_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
    'カスタムフィルタのValueChangedイベントを発生し、グリッドにフィルタを適用します
        OnValueChanged()
    End Sub
    
    private void MultiSelect_SelectionChanged(object sender, EventArgs e)
    {
        //カスタムフィルタのValueChangedイベントを発生し、グリッドにフィルタを適用します
        OnValueChanged();
    }
    
  4. Implement the GetExpression abstract method of the CustomFilter class to create and return the filter expression which is to be used to filter the values in the data aware control.
    Protected Overrides Function GetExpression() As Expression
                'フィルタ式を作成して返します
            Dim ce = New CombinationExpression() With {
                .FilterCombination = FilterCombination.[Or]
            }
    
            For Each item In _multiSelect.SelectedItems
                ce.Expressions.Add(New OperationExpression() With {
                    .FilterOperation = FilterOperation.Equal,
                    .Value = item.Value,
                    .PropertyName = PropertyName
                })
            Next
    
            Return ce
        End Function
            'このプロパティは、フィルタが適用されるかどうかを決定します
        Public Overrides ReadOnly Property IsApplied As Boolean
            Get
                Return MyBase.IsApplied AndAlso _multiSelect.SelectedItems.Count > 0
            End Get
        End Property
    
    protected override Expression GetExpression()
    {
        //フィルタ式を作成して返します
        var ce = new CombinationExpression() { FilterCombination =
            FilterCombination.Or };
        foreach (var item in _multiSelect.SelectedItems)
            ce.Expressions.Add(new OperationExpression() {
                FilterOperation = FilterOperation.Equal,
                Value = item.Value, PropertyName = PropertyName });
        return ce;
    }
    
    //このプロパティは、フィルタが適用されるかどうかを決定します
    public override bool IsApplied => base.IsApplied &&
        _multiSelect.SelectedItems.Count > 0;
    
  5. Add the created custom filter, ModelFilter, to the DataFilter control to filter the car models shown in the FlexGrid control.
    Dim _carsTable As DataTable
    
    Public Sub New()
        InitializeComponent()
        Me.Load += Form1_Load
    End Sub
    
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
        Dim con As OleDbConnection = New OleDbConnection(
                    "provider=microsoft.jet.oledb.4.0;Data Source=" & 
                    Environment.GetFolderPath(Environment.SpecialFolder.Personal) & 
                    "\ComponentOne Samples\Common\C1NWind.mdb")
        _carsTable = New DataTable()
        New OleDbDataAdapter("Select * from Cars", con).Fill(_carsTable)
        c1DataFilter1.DataSource = GetCars().ToList()
        c1FlexGrid1.DataSource = GetCars().ToList()
            
        'カスタムモデルフィルタを初期化します
        'MultiSelectコントロールを使用して自動車のモデルをフィルターできます
        Dim modelFilter = New ModelFilter() With {
            .HeaderText = "Model",
            .PropertyName = "Model"
        }
            'MultiSelectコントロールのデータを設定します
        modelFilter.SetTagList(GetCars().ToList())
            
       'MultiSelectコントロールをカスタマイズして、コントロール
      'のヘッダーに5個以下の項目を表示します
        modelFilter.MultiSelect.MaxHeaderItems = 5
            
            'FilterCollectionにカスタムフィルターを追加します
        c1DataFilter1.Filters.Add(modelFilter)
            
            'FilterChangedイベントに購読します
        c1DataFilter1.FilterChanged += C1DataFilter1_FilterChanged
    End Sub
    
    Private Sub C1DataFilter1_FilterChanged(ByVal sender As Object, ByVal e As EventArgs)
            'データを更新します
        c1FlexGrid1.DataSource = c1DataFilter1.View.Cast(Of Car)().ToList()
    End Sub
    
    Public Iterator Function GetCars() As IEnumerable(Of Car)
        Dim carsTable = _carsTable
    
        For Each row As DataRow In carsTable.Rows
            Yield New Car With {
                .Brand = row.Field(Of String)("Brand"),
                .Category = row.Field(Of String)("Category"),
                .Description = row.Field(Of String)("Description"),
                .Liter = row.Field(Of Double)("Liter"),
                .Model = row.Field(Of String)("Model"),
                .Picture = row.Field(Of Byte())("Picture"),
                .Price = row.Field(Of Double)("Price"),
                .TransmissAutomatic = row.Field(Of String)("TransmissAutomatic"),
                .ID = row.Field(Of Integer)("ID")
            }
        Next
    End Function
    
    DataTable _carsTable;
    public Form1()
    {
        InitializeComponent();
        this.Load += Form1_Load;
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        OleDbConnection con = new OleDbConnection(
            "provider=microsoft.jet.oledb.4.0;Data Source=" +
            Environment.GetFolderPath(Environment.SpecialFolder.Personal) +
            "\\ComponentOne Samples\\Common\\C1NWind.mdb");
        _carsTable = new DataTable();
    
        new OleDbDataAdapter("Select * from Cars", con).Fill(_carsTable);
    
        c1DataFilter1.DataSource = GetCars().ToList();
        c1FlexGrid1.DataSource = GetCars().ToList();
    
        //カスタムモデルフィルタを初期化します
        //MultiSelectコントロールを使用して自動車のモデルをフィルタできます
        var modelFilter = new ModelFilter()
        {
            HeaderText = "Model",
            PropertyName = "Model",                
        };
    
        //MultiSelectコントロールのデータを設定します
        modelFilter.SetTagList(GetCars().ToList());
    
        //MultiSelectコントロールをカスタマイズして、コントロール
        //のヘッダーに5個以下の項目を表示します
        modelFilter.MultiSelect.MaxHeaderItems = 5;
    
        //FilterCollectionにカスタムフィルタを追加します
        c1DataFilter1.Filters.Add(modelFilter);
    
        //FilterChangedイベントに購読します
        c1DataFilter1.FilterChanged += C1DataFilter1_FilterChanged;
    }
    
    private void C1DataFilter1_FilterChanged(object sender, EventArgs e)
    {
        //データを更新します
        c1FlexGrid1.DataSource = c1DataFilter1.View.Cast<Car>().ToList();
    }
    
    public IEnumerable<Car> GetCars()
    {
        var carsTable = _carsTable;
        foreach (DataRow row in carsTable.Rows)
        {
            yield return new Car
            {
                Brand = row.Field<string>("Brand"),
                Category = row.Field<string>("Category"),
                Description = row.Field<string>("Description"),
                Liter = row.Field<double>("Liter"),
                Model = row.Field<string>("Model"),
                Picture = row.Field<byte[]>("Picture"),
                Price = row.Field<double>("Price"),
                TransmissAutomatic = row.Field<string>("TransmissAutomatic"),
                ID = row.Field<int>("ID")
            };
        }
    }
    

Similarly, you can create any other custom filters.