We use the text search filter from the WPF GridView examples for filtering the grids, which works fine.
Our customer has the following requirement: they want to be able to filter numeric columns using a contains operator similar to the string filtering. This is especially useful when searching for e.g. serial numbers.
We could not find a solution for this issue in the GridView forum. We do not want to change the data type of the numeric columns of the view model into a string because of the amount of grids used by the application. We want to implement a custom FilterDescriptor that will be created by the TextSearch behavior when it detects a numeric column.
Can you please provide us an example implementation of a custom filter that shows how to implement this behavior?
Kind
regards,
Bert
11 Answers, 1 is accepted
The actual filtering is always performed on the actual data. There is a property called FilterMemberPath to the column class which allows you to bind to one property and filter by another property on the business object class. In your case, you can expose a new property (of type string) and set it as a filter path.
I would suggest you to check our online documentation to understand how the filtering is actually performed.
Hopefully this helps.
Regards,
Didie
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Filtering on another property of type string is exactly what we do not want to do. This means that we have to add an additional property to the business object for each numeric property that is shown in a grid. Since we have a lot of grids, this is not the preferred solution.
Each grid filtered by a class that is implemented as an attached behaviour for a grid view, similar to the grid view demo. So the most logical and clear solution is to handle it there using a custom filter for this purpose.
Please provide us an example implementation of a custom filter that shows how to implement this behavior.
Kind regards,
Bert
Filtering is a data operation and it is always performed on actual underlying data. As a data operation, filtering does not depend on what the user sees on the screen. Even if you apply a converter to show strings and not numeric values, this will not change the way the values will be filtered.
The reason is because the IValueConverters and the string formats are UI tools which can only change the appearance of things on the screen but they do not play any part in our LINQ data engine. The data that sits below is still the original "raw" data and this is the data that filtering is done on. All of these concepts are described in this help topic.
Having the above in mind, you need to shape your data accordingly.
The easiest approach is the one I already suggested. I will try to explain it in more details: it would be to add a new read-only string property to your business object class - it will read the integer 1 and return the string "1". Then, you can set the FilterMemberPath of your column to point to this new property. In this way, the column will still be bound to the original numeric property, but the filtering will be performed on your string property.
You can also check our section on Custom Filtering Controls.
Regards,
Didie
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
We are not using a filter control, we are using a textbox to filter a grid using an attached behavior which is almost identical to the attached code from the grid view search demo’s.
In method CreateFilterForColumn a FilterDescriptor is created for a column. The filter operator is set to FilterOperator.Contains for a string column and FilterOperator.IsEqualTo for all other columns. See code below:
private IFilterDescriptor CreateFilterForColumn(GridViewDataColumn column)
{
FilterOperator filterOperator = GetFilterOperatorForType(column.DataType);
FilterDescriptor descriptor = new FilterDescriptor(column.UniqueName, filterOperator, this.filterValue);
descriptor.MemberType = column.DataType;
return descriptor;
}
private static FilterOperator GetFilterOperatorForType(Type dataType)
{
return dataType == typeof(string) ? FilterOperator.Contains : FilterOperator.IsEqualTo;
}
Wat we need is an example of how to create a custom FilterDescriptor that does a contains operation for a numeric column. It will work for all numeric columns in all grids if we simply return this FilterDescription in method CreateFilterForColumn. This a clean solution without the need to spend a lot of work adding properties that are only used for filtering.
In short, please provide an example of how to create this custom FilterDescriptor.
Kind regards,
Bert Polman
I am afraid there is not a way to create such a custom FilterDescriptor.
Regards,
Didie
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
I do not understand why this is so difficult. The only difference between a contains filter on a string property and a numeric property is that ToString() must be called for a numeric property. Everything else is the same.
Kind regards,
Bert
The difference is that the original property is of a numeric type and you would like to work with with as if it is a string (numericPropertyValue.ToString()).
Please keep in mind the filtering is a data operation. This means it is always performed on actual underlying data through building and executing a LINQ query over the source collection). As a data operation, filtering does not depend on what the user sees on the screen (and how the data is additionally formatted).
It will work if such a query can be build and executed successfully.
For example, such a query could be:
var result = boundCollection.Where(item => item.
NumericValue == "19203");
Regards,
Didie
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Yes building such a query is possible. There only needs to be a check an a null value. E.g. :
var result = boundCollection.Where(item => (item.NumericValue !=
null
)&& (item.NumericValue.ToString().Contains(
"19203"
));
An additional check is needed when the property is a property of a sub object (item.Sub.NumericValue != null).
Kind Regards,
Bert
Indeed, you are right, you can manually invoke item.NumericValue.ToString(). Still, internally we cannot know that you want to convert your numeric value to string.
If you want to define your own filtering control instead of the built-in one, you can check our documentation on Custom Filtering Controls.
Regards,
Didie
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
The Custom Filtering Controls document you ar pointing at is about how to make a custom filter control. It does not describe how to make a custom filter that can be used in the method CreateFilters of the example in that document. A Telerik.Windows.Data.FilterDescriptor is created there. The only thing we need is a FilterDescriptor that is capable to do a contains operation on a numeric value.
The FilterDescriptor has sufficient information to know when to convert the numeric value to a string. It must be done when property FilterDescriptor.MemberType is set to a numeric type and FilterOperator.Contains is provided as the second parameter to the constructor of the FilterDescriptor class.
Kind Regards,
Bert
The FilterDescriptor itself is not capable of performing such an operation.
I am afraid that the LINQ data engine does not expose any event to override the LINQ logic. You will have to code your own filter mechanism -- when it is possible.
In your case you can develop a method (called predicate) to execute the filtering - so you can benefit from our generic class FilterDescriptor<T>.
The FilterDescriptor<T> allows you to directly plug a predicate that determines which items are filtered. You just need to set a lambda to the FilteringExpression property like so:
var descriptor = new
FilterDescriptor<Employee>
{
FilteringExpression = employee => this.PassesFilter(employee)
};
private bool PassesFilter(Employee employee, <<your filtering criteria gathered from the custom filtering control UI>>){...}
I hope this helps.
Regards,
Didie
Telerik