This is a migrated thread and some comments may be shown as answers.

Filtering Percentage values

12 Answers 247 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Alan
Top achievements
Rank 1
Alan asked on 29 Apr 2014, 11:36 AM
I have formatted a column in a gridview by using the dataformatstring attribute {0:P0}.
This changes my 0.32 values to 32 and displays percentages as I want it to, but when entering a value in the field filters, I need to enter the original value to get it to filter correctly. e.g 0.32 for 32

I'm hoping there is an easy way of intercepting the 32 value and changing it back to 0.32 for the purposes of filtering.

I've tried using the FieldFilterEditorCreated event on the grid and accessing the e.Editor (which seems to be a textbox with more properties), but I can't see anything in there that allows me to hijack the value and change it from 32 to 0.32.
I've also tried using the Filtering Event, and successfully transformed the 'Value' property of the filterdescriptors, but this change does not seem to be retained/passed through to the datasource

I'm aware that it could be that I need to create a new custom filtering control, but this seems very laborious, when all I want to do is retain the formatting of the column when filtering. 

I have three questions really, 
(1) Is there a way of transforming/intercepting the value passed to the datasource for filtering?
(2) Is creating a new custom filtering control the only way to do what I need to do
(3) If so, is there an example I can follow that focusses on the textbox filtering control, as opposed to the date filter as in this tutorial http://www.telerik.com/help/wpf/gridview-filtering-custom-filtering-controls.html

Many thanks
Alan

12 Answers, 1 is accepted

Sort by
0
Raymond
Top achievements
Rank 1
answered on 29 Apr 2014, 11:20 PM
I use a ValueConverter to convert values displayed in the grid as follows;
<UserControl x:Class="UserControl1"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             xmlns:rad="clr-namespace:DCRAD"
             .
             .
             .>
 
<UserControl.Resources>
    .
    .
    .
    <!-- Value Converters -->
    <rad:NumberToFixedStringConverter x:Key="NumberToFixedString" />
    .
    .
    .
</UserControl.Resources>
 
<telerik:RadGridView>
    <telerik:RadGridView.Columns>
        .
        .
        .
        <telerik:GridViewDataColumn Header="Distance" UniqueName="Distance" Width="auto">
            <telerik:GridViewDataColumn.AggregateFunctions>
                <telerik:SumFunction ResultFormatString="{} {0:0.00}" />
            </telerik:GridViewDataColumn.AggregateFunctions>
 
            <telerik:GridViewDataColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Distance, Converter={StaticResource NumberToFixedString}, ConverterParameter=0.00}" HorizontalAlignment="Right" />
                </DataTemplate>
            </telerik:GridViewDataColumn.CellTemplate>
        </telerik:GridViewDataColumn>
        .
        .
        .
    </telerik:RadGridView.Columns>
</telerik:RadGridView>

And the ValueConverter looks like;
Imports System
Imports System.ComponentModel
Imports System.Windows.Data
 
<ValueConversion(GetType(Object), GetType(Object))>
Public Class NumberToFixedStringConverter
    Implements IValueConverter
 
    Public Function Convert(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
        Dim sValue As String = String.Empty
        Dim sParam As String = "0.00"
 
        Try
            sValue = value.ToString
            If parameter IsNot Nothing Then sParam = parameter.ToString
 
            If IsNumeric(sValue) Then
                If Val(sValue) = 0 Then
                    'If the parameter starts with "+" then return a formatted string; otherwise return an empty string...
                    If sParam.StartsWith("+") Then
                        sValue = sParam.Substring(1)
                    Else
                        sValue = String.Empty
                    End If
                Else
                    If sParam.StartsWith("+") Then
                        sValue = Format(CType(sValue, Double), sParam.Substring(1))
 
                        'If the value is less than the precision to be displayed...
                        If sValue = Format(CType(0, Double), sParam.Substring(1)) Then sValue = sParam.Substring(1)
                    Else
                        sValue = Format(CType(sValue, Double), sParam)
 
                        'If the value is less than the precision to be displayed...
                        If sValue = Format(CType(0, Double), sParam) Then sValue = String.Empty
                    End If
                End If
            End If
        Catch ex As Exception
            'Don't action the error and return the empty string...
        End Try
 
        Return sValue
    End Function
 
    Public Function ConvertBack(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
        Dim sValue As String = String.Empty
        Dim oValue As Object = 0
 
        Try
            sValue = value.ToString
 
            If (sValue.Length > 0) Then
                If sValue.EndsWith("%") Then sValue = sValue.Substring(0, sValue.Length - 1)
 
                If IsNumeric(sValue) Then
                    oValue = Val(sValue)
                End If
            End If
        Catch ex As Exception
            'Don't do anything - return a zero value...
        End Try
 
        Return oValue
    End Function
End Class
0
Alan
Top achievements
Rank 1
answered on 30 Apr 2014, 08:05 AM
Thanks for your reply Raymond.
However, unless i've got something wrong, your post seems to be converting values from the datasource/object to percentages for  displaying in the cells.

I use the data format string for this purpose, as below...

<telerik:GridViewDataColumn  Header="GLH Profile SSA3" DataMemberBinding="{Binding GLHProfile_SSA3}" IsFilterable="True" DataFormatString="{} {0:P1}"/>

I'm looking to convert the value from the percentage, back to the decimal value, at the point of filtering, so that the datasource can be filtered correctly.

Thanks
Alan

0
Dimitrina
Telerik team
answered on 30 Apr 2014, 09:17 AM
Hello Alan,

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 would be to add a new read-only string property to your business object class - it will read the original value and return the formatted string. 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 the following forum thread where a similar topic was already discussed:
Custom Filter.

Regards,
Didie
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Alan
Top achievements
Rank 1
answered on 30 Apr 2014, 09:35 AM
Thanks for your response Didie.

I fully understand that filtering is a data operation and is performed on underlying data. But it is the value in the filter textbox that I want to convert, so that it is in the correct format to filter the data. 
It is possible to convert the data to a percentage, to be seen in the gridcell, but it seems it is not possible to convert the value in the textbox back to its original format...

It seems (from your response and the topic you have mentioned) that the only way to go about this is to create a custom filter, so that when the user enters 30 in the text box, I can convert this to 0.30, before passing it to be filtered.

I would've thought that this would've been a lot easier than this, and for reasons that I have mentioned already in this topic (and by others in other topics) it is perhaps something telerik might want to look at making easier?

In the meantime, could you please supply me with an example on how to create a textbox custom filter, as the only examples I can find use datepickers and not strings?

Thanks
Alan
0
Dimitrina
Telerik team
answered on 30 Apr 2014, 01:04 PM
Hello Alan,

You can also check our online documentation for a better understanding on how the filtering works:
Basic Filtering.

The approach I recommend is exposing a new property to be filtered on and set it as FilterMemberPath for the respective column.

Regards,
Didie
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Alan
Top achievements
Rank 1
answered on 30 Apr 2014, 01:07 PM
Thank you for your reply

I am aware of how the filtering works and the possibilities of exposing a new properties, but this is not the way I wish to proceed.

Can you please provide me with an example of creating a custom filter using the textbox?

Regards
Alan
0
Dimitrina
Telerik team
answered on 30 Apr 2014, 02:06 PM
Hi Alan,

I am afraid we do not have such an example. You will have to implement your custom logic serving the particular case. 
The example you can check is creating a custom filtering control with ComboBox. Still, you need to add proper code in the CreateFilters() method. This code should include adding a generic filter descriptor (FilterDescriptor<T>) to build the proper LINQ query to filter on.

Regards,
Didie
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Alan
Top achievements
Rank 1
answered on 30 Apr 2014, 02:13 PM
Sorry, can you give me more information than that please?

The link to a custom filter you have provided is not for a combobox, but for a datepicker. Is there one for a combobox? I may be able to follow this better.
The link to the filter descriptor you have provided does not work.

I'm at a bit of a loss as to how to go about building a custom control through lack of documentation, examples and advice for this topic.
0
Alan
Top achievements
Rank 1
answered on 30 Apr 2014, 02:15 PM
Can you point me in the direction of the code used to build the default textbox filter?
0
Raymond
Top achievements
Rank 1
answered on 30 Apr 2014, 08:35 PM
Hi Alan,

The "Convertback" procedure in the ValueConverter is used to manipulate the value entered by the user.  For example, if your user entered "32" you can use the "ConvertBack" procedure to convert it to "0.32" as follows;
Public Function ConvertBack(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
        Dim sValue As String = String.Empty
        Dim oValue As Object = 0
  
        Try
            sValue = value.ToString
  
            If (sValue.Length > 0) Then
                If IsNumeric(sValue) Then
                    oValue = CType(sValue, Double)
                    If oValue > 1 then oValue = oValue / 100
                End If
            End If
        Catch ex As Exception
            'Don't do anything - return a zero value...
        End Try
  
        Return oValue
    End Function
0
Raymond
Top achievements
Rank 1
answered on 30 Apr 2014, 10:20 PM
Hi Alan,

My mistake - I though you were attempting to convert the values in the grid not in the filter dropdown.

Regards,

Ray
0
Dimitrina
Telerik team
answered on 01 May 2014, 07:44 AM
Hi,

I apologize for my mistake, indeed this example is with DatePicker. We have an example with ComboBox for RadDataFilter: Create Custom Filter Editors.

You can always change the default editor for RadGridView similarly yo RadDataFilter. So you will have your own custom editor in place of the default one (i.e. the TextBox that we provide by default). 

Replacing the default filter editor is described in our documentation: Create a Custom Field Filter Editor.


Regards,
Didie
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
Tags
GridView
Asked by
Alan
Top achievements
Rank 1
Answers by
Raymond
Top achievements
Rank 1
Alan
Top achievements
Rank 1
Dimitrina
Telerik team
Share this question
or