Filtering Percentage values

13 posts, 0 answers
  1. Alan
    Alan avatar
    12 posts
    Member since:
    Aug 2012

    Posted 29 Apr 2014 Link to this post

    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
  2. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 29 Apr 2014 in reply to Alan Link to this post

    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
  3. Alan
    Alan avatar
    12 posts
    Member since:
    Aug 2012

    Posted 30 Apr 2014 in reply to Raymond Link to this post

    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

  4. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 30 Apr 2014 Link to this post

    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.
     
  5. Alan
    Alan avatar
    12 posts
    Member since:
    Aug 2012

    Posted 30 Apr 2014 in reply to Dimitrina Link to this post

    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
  6. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 30 Apr 2014 Link to this post

    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.
     
  7. Alan
    Alan avatar
    12 posts
    Member since:
    Aug 2012

    Posted 30 Apr 2014 in reply to Dimitrina Link to this post

    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
  8. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 30 Apr 2014 Link to this post

    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.
     
  9. Alan
    Alan avatar
    12 posts
    Member since:
    Aug 2012

    Posted 30 Apr 2014 in reply to Dimitrina Link to this post

    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.
  10. Alan
    Alan avatar
    12 posts
    Member since:
    Aug 2012

    Posted 30 Apr 2014 in reply to Dimitrina Link to this post

    Can you point me in the direction of the code used to build the default textbox filter?
  11. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 30 Apr 2014 in reply to Alan Link to this post

    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
  12. Raymond
    Raymond avatar
    65 posts
    Member since:
    Oct 2013

    Posted 30 Apr 2014 in reply to Raymond Link to this post

    Hi Alan,

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

    Regards,

    Ray
  13. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 01 May 2014 Link to this post

    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.
     
Back to Top