ComponentOne DataFilter for WPF
Walkthrough / Using DataFilter with FlexGrid
In This Topic
    Using DataFilter with FlexGrid
    In This Topic

    FlexGrid provides built-in filtering support with the help of column filters. However, consider a scenario where you want a filtering UI similar to the one seen in different e-commerce websites where a grid displaying the product listing shows only few attributes such as the product image, product name and product price. Although, the user is allowed to filter the product listing by many other attributes such as brand, category, price etc. It is not possible to set such kind of filters from column filters in data grid controls. Hence, this walkthrough explains how you can use the DataFilter control to filter FlexGrid content using a filtering UI similar to any online store’s website.

    To create an application for filtering a car list by brand, category, and price, complete the following steps:

    1. Setting up the application UI
    2. Creating data source for FlexGrid and DataFilter
    3. Adding data to FlexGrid and DataFilter controls

    The following image shows a list of cars filtered by a specific brand, category and price in FlexGrid using the DataFilter control.

    The image depicts the filtering control datafilter showing the filtering operation of different car models.

    Step 1: Setting up the application UI

    1. Create a new WPF App in Visual Studio.
    2. Drag and drop the C1DataFilter and C1FlexGrid controls from the toolbox onto the form. Note that the following references get automatically added to the References.
      • C1.WPF.DataFilter4.5.2.dll
      • C1.WPF.4.5.2.dll
      • C1.WPF.DateTimeEditors.4.5.2.dll
      • C1.WPF.Extended.4.5.2.dll
      • C1.DataCollection.4.5.2.dll
      • C1.WPF.DataGrid.4.5.2.dll
      • C1.DataCollection.BindingList.dll
    3. Open MainWindow.xaml and replace the existing XAML with the following code.
      XAML
      Copy Code
      <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:local="clr-namespace:C1FlexGrid_DataFilter"
      xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml" x:Class="C1FlexGrid_DataFilter.MainWindow"
      mc:Ignorable="d"
      Title="DataFilter" Height="900" Width="1061.526">
      <Grid>
      <Grid.ColumnDefinitions>
      <ColumnDefinition Width="475*"/>
      <ColumnDefinition Width="317*"/>
      </Grid.ColumnDefinitions>
      <c1:C1FlexGrid RowDetailsVisibilityMode="Visible" Name="grid" HorizontalAlignment="Left" Margin="317,0,0,0" VerticalAlignment="Top" Height="809" Width="650" Grid.ColumnSpan="2">
      <c1:C1FlexGrid.Columns>
      <c1:Column Header="Brand" Binding="{Binding Brand}" Width="150" />
      <c1:Column Header="Model" Binding="{Binding Model}" Width="150" />
      <c1:Column Header="Price" Binding="{Binding Price}" Width="150" />
      <c1:Column Header="Category" Binding="{Binding Category}" Width="150" />
      </c1:C1FlexGrid.Columns>
      <c1:C1FlexGrid.RowDetailsTemplate>
      <DataTemplate>
      <DockPanel Background="GhostWhite">
      <Image DockPanel.Dock="Left" Name="img" Source="{Binding Picture}"
      Height="64" Margin="10" />
      <Grid Margin="0, 10">
      <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <TextBlock Text="Brand: " FontWeight="Bold" />
      <TextBlock Text="{Binding Brand}" Grid.Column="1" />
      <TextBlock Text="Model: " FontWeight="Bold" Grid.Row="1" />
      <TextBlock Text="{Binding Model}" Grid.Column="1" Grid.Row="1" />
      <TextBlock Text="Price: " FontWeight="Bold" Grid.Row="2" />
      <TextBlock Text="{Binding Price}" Grid.Column="1" Grid.Row="2" />
      </Grid>
      </DockPanel>
      </DataTemplate>
      </c1:C1FlexGrid.RowDetailsTemplate>
      </c1:C1FlexGrid>
      <c1:C1DataFilter Name="c1DataFilter" FilterAutoGenerating="C1DataFilter_FilterAutoGenerating" HorizontalAlignment="Left" VerticalAlignment="Top" Height="705" Width="312" Margin="0,104,0,0"/>
      <Image Margin="0" Stretch="Fill" Source="/CarLogo.png" HorizontalAlignment="Left" Height="192" VerticalAlignment="Top" Width="312"/>
      </Grid>
      </Window>
      

    Back to Top

    Step 2: Creating data source for FlexGrid and DataFilter

    Add a class 'Car' to define data.

    Public Iterator Function GetCarDataCollection(ByVal carTable As DataTable) As IEnumerable(Of car)
        Dim rnd As New Random()
    
        For Each row As DataRow In carTable.Rows
    
            Yield New car With {
                .Brand = row.Field(Of String)("Brand"),
                .Model = row.Field(Of String)("Model"),
                .Picture = row.Field(Of Byte())("Picture"),
                .Price = row.Field(Of Double)("Price"),
                .Category = row.Field(Of String)("Category")
            }
    
        Next row
    
    End Function
    
    Public Function GetCarTable() As DataTable
        Dim rs As String = "select * from Cars;"
        Dim cn As String = GetConnectionString()
        Dim da As New OleDbDataAdapter(rs, cn)
        Dim dt As New DataTable()
        da.Fill(dt)
        Return dt
    End Function
    
    Private Function GetConnectionString() As String
        AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.Personal) & "\ComponentOne Samples\Common")
        Dim conn As String = "provider=microsoft.jet.oledb.4.0;data source=|DataDirectory|\c1nwind.mdb;"
        Return conn
    End Function
    
    public IEnumerable<Car> GetCarDataCollection(DataTable carTable)
    {
        Random rnd = new Random();
    
        foreach(DataRow row in carTable.Rows)
        {
            
            yield return new Car
            {
                Brand = row.Field<string>("Brand"),
                Model = row.Field<string>("Model"),
                Picture = row.Field<Byte[]>("Picture"),
                Price = row.Field<double>("Price"),
                Category = row.Field<string>("Category")
    
            };
    
        }
      
    }
    
    public DataTable GetCarTable()
    {
        string rs = "select * from Cars;";
        string cn = GetConnectionString();
        OleDbDataAdapter da = new OleDbDataAdapter(rs, cn);
        DataTable dt = new DataTable();
        da.Fill(dt);
        return dt;
    }
    
    private string GetConnectionString()
    {
        AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\ComponentOne Samples\Common");
        string conn = @"provider=microsoft.jet.oledb.4.0;data source=|DataDirectory|\c1nwind.mdb;";
        return conn;
    }
    

    Step 3: Adding data to FlexGrid and DataFilter controls

    1. Populate the FlexGrid and DataFilter controls with data.
      ' Initialize the data
      _carsTable = _dataProvider.GetCarTable()
      Dim Data = New C1DataCollection(Of car)(_dataProvider.GetCarDataCollection(_carsTable))
      ' Populate the grid and filter with data
      grid.ItemsSource = Data
      c1DataFilter.ItemsSource = Data
      grid.AutoGenerateColumns = False
      
      //Initialize the data
      _carsTable = _dataProvider.GetCarTable();
      var data = new C1DataCollection<Car>(_dataProvider.GetCarDataCollection(_carsTable));
      
      //Populate the grid and filter with data
      grid.ItemsSource = data;
      c1DataFilter.ItemsSource = data;
      grid.AutoGenerateColumns = false;
      
    2. Add the following code in the event handler of the FilterAutoGenerating event which provides the checklist items for the two filters namely “Brand”, “Category” and sets the maximum and minimum value for the price filter.
      Defining these filters allows you to filter the cars listing by a specific brand, category or price which are the basic criteria used to view a car listing.
      Private Sub C1DataFilter_FilterAutoGenerating(sender As Object, e As C1.DataFilter.FilterAutoGeneratingEventArgs)
          Select Case e.[Property].Name
              Case "Brand"
                  Dim BrandFilter = CType(e.Filter, ChecklistFilter)
                  BrandFilter.SelectAll()
              Case "Category"
                  Dim CategoryFilter = CType(e.Filter, ChecklistFilter)
                  CategoryFilter.SelectAll()
              Case "Price"
                  Dim priceFilter = CType(e.Filter, RangeFilter)
                  priceFilter.Maximum = _carsTable.AsEnumerable().Max(Function(x) x.Field(Of Double)("Price"))
                  priceFilter.Minimum = _carsTable.AsEnumerable().Min(Function(x) x.Field(Of Double)("Price"))
                  priceFilter.Increment = 1000
                  priceFilter.Digits = 0
              Case Else
                  e.Cancel = True
          End Select
      End Sub
      
      private void C1DataFilter_FilterAutoGenerating(object sender, C1.DataFilter.FilterAutoGeneratingEventArgs e)
      {
          switch (e.Property.Name)
          {
              case "Brand":
                  var BrandFilter = (ChecklistFilter)e.Filter;
                  BrandFilter.SelectAll();
                  break;
              case "Category":
                  var CategoryFilter = (ChecklistFilter)e.Filter;
                  CategoryFilter.SelectAll();
                  break;
             
              case "Price":
                  var priceFilter = (RangeFilter)e.Filter;
                  priceFilter.Maximum = _carsTable.AsEnumerable().Max(x => x.Field<double>("Price"));
                  priceFilter.Minimum = _carsTable.AsEnumerable().Min(x => x.Field<double>("Price"));
                  priceFilter.Increment = 1000;
                  priceFilter.Digits = 0;
                  break;
              default:
                  e.Cancel = true;
                  break;
          }
      }
      
    3. Run the application and observe how the cars data with image appear in the FlexGrid control while all the car attribute filters are added to the DataFilter control.
      Now, you can change the filter values in the DataFilter UI and see how the FlexGrid renders the filtered data.

    Back to Top