What if I have created a INativeReport and I want to filter it, but the build in filters are not exactly what I need?

 

Well you can create your own filters! It does require some coding though (but we like code, right?).

 

As an example let’s add a “Region” filter to the “Customers Grouped by Region” report I created in my last post. To do this I need to create a new class that implements IReportFilterGenericV2 and ISerializable.

 

If you use Visual Studio to implement the IReportFilterGenericV2 interface you will notice a few sections. I’ll run through them quickly:

  •  IReportFilterGenericV2 Members
    • public void ClearAll() - This method is called if the user clicks the clear button in the filter dialog. Basically you should set the state of the filter back to the default value or “All”.
    • public IFilterOptionV2[] GetFilterBarOptions(IReportFiltersV2 reportFilters) - The filter can be shown in two places: the filter bar (above the report) or in the filter dialog. This method should return the options to show in the filter bar.
    • public IFilterOptionV2[] GetFilterDialogOptions(IReportFiltersV2 reportFilters) - This method should return the options to show in the filter dialog
  • IReportFilterV2 Members
    • public ReportFilterEnum FilterEnumValue - This Property is used to identify the filter, for Generic filters it should always return ReportFilterEnum.GenericFilter.
    • public string GetDisplayValue(ISmallBusinessInstance instance) - This method should return the value you want to show in the Filter text in the header of the report.
    • public string Label - This is the label used in the filter dialog on the left hand side
    • public void SetValues(IReportFilterV2 filter) - This method is used to move the values from one instance of the filter to another. Basically you should make sure all of your instance data is copied from the argument to “this”.
    • public bool Visible - A property used to hide the filter. You should simple save this state in a variable so you can return it in the getter.

  • ICloneable Members
    • public object Clone()- Standard implementation of ICloneable, here you would typically use the SetValue method for an easy implementation.

For the ISerializable implementation is pretty standard, the serialization is used when users save the report:

  • ICloneable Members
    • public void GetObjectData(SerializationInfo info, StreamingContext context) - This method should add the instance data from the filter to the SerializationInfo object (used when serializing).
    • public ctor(SerializationInfo info, StreamingContext context) - You need to create a special constructor for the de-serialization, the constructor should set the instance data from the SerializationInfo object (this is used when the user launches the saved report).

I have put a sample implementation of IReportFilterGenericV2 on this page if you would rather look at code…

 

With all of that work we now have a new filter that will show in the top filter bar in a report and in the filter dialog. To use it we have to add it to the report.

 

First we need to add the new filter to the report, to do that we add a few lines in the CreateFilters method:

 

// Add the region filter to the filter collection as a generic filter

RegionFilter regionFilter = new RegionFilter();

reportFilters.AddGenericFilter(regionFilter);

 

To actually use the filter we will need to apply the filter in the CreateData method. Naturally the implementation here will vary based on what you expect your filter to do, but I hope you get the idea from this sample:

 

if (reportFilters.ContainsFilter(ReportFilterEnum.GenericFilter))

{

    RegionFilter reportRegionFilter

        = reportFilters.GetFilter(ReportFilterEnum.GenericFilter)

            as RegionFilter;

 

    // apply region filter

 

    if (String.IsNullOrEmpty(reportRegionFilter.State) == false)

    {

        if (filterString.Length > 0)

            filterString.Append(" AND ");

        filterString.Append("State = '");

        filterString.Append(reportRegionFilter.State);

        filterString.Append("'");

    }

 

    else if (reportRegionFilter.CensusRegion != (int)CensusRegions.All)

    {

        if (filterString.Length > 0)

            filterString.Append(" AND ");                   

        filterString.Append(

            RegionFilter.GetCensusRegion(reportRegionFilter.CensusRegion));

    }

}

 

// Apply row filter

if (filterString.Length > 0)

    view.RowFilter = filterString.ToString();

 

The result is a nice report with a custom filter:

 Report with custom filter