RadDataFilter and Value Converters

5 posts, 1 answers
  1. Mark
    Mark avatar
    44 posts
    Member since:
    Jun 2009

    Posted 08 Feb 2011 Link to this post

    Hello,

    I am looking for general advice/guidance on using the RadDataFilter when the filtered result is displayed in a Grid that uses Value Converters.  Let me paint the scenario...

    In the general use case, the RadDataFilter accepts a Source and emits a FilteredItemSource.  The Source is the collection of items to be filtered, and the Filtered ItemSource is the result of the filter, that can be bound to some other control like the RadGridView.  However, if a column in the GridView used to display the results uses a Value Converter to modify the displayed value in any way, you can get into a problem that will cause a lot of confusion to the user.  Namely, the filter no longer operates on values as displayed in the grid.  So when the user enters filter criteria, the grid may not filter as expected because the user is most likely entering values that match the display in the grid, while the filter is operating on the underlying values. 

    I believe that this problem can also be demonstrated when perhaps the backing data contains a value of type double, while the datagrid uses a string format to show the value as a percent.

    Although I believe I know why things are working this way, I am wondering what the best-practices might be to get things to work as expected from the user.  Should we refrain from using Value Converters in the display, and instead do the conversion in the backing store (i.e. the RadDataFilter's Source collection) hence operating on raw values only?  If so, this seems a little unfortunate.  Is there another approach that might be helpful here?

    I am curious to hear whether anyone else has run into this problem and what you might have done.

    Thanks,
    Mark.
  2. Answer
    Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 09 Feb 2011 Link to this post

    Hi Mark,

    I was about to suggest creating new properties (proxies to the "real") on the POCO that will render the IValueConverter obsolete and provide the end user with consistent experience. I think that this is the easiest way. In fact, the new prop will be a read-only string prop and will juts return what the IValueConverter is currently doing.

    The other option would be to develop you custom filter editor that will accept the string "2 dollars" and covert it to the double 2.00, for example. That is because if the actual relevant property is a double, then the Value of the FilterDescriptor object that is produced has to be a double also. There is no magical way to convert the user-friendly string to the actual meaningful double. That is because under the hood our data engine will produce a LINQ expression of the form:

    collection.Where(product => product.Price > 2.99)

    So if Product.Price is a double, then 2.99 has to be a double as well. It cannot be "2 dollars and ninety-nine cents" because it will crash.

    So it is up to you to decide which way will be easier for you.

    I hope this helps.

    Greetings,
    Ross
    the Telerik team
    Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
  3. UI for WPF is Visual Studio 2017 Ready
  4. Mark
    Mark avatar
    44 posts
    Member since:
    Jun 2009

    Posted 09 Feb 2011 Link to this post

    Hi Ross,

    Thanks again for your reply and support.

    I have already started implementing your first option as it is the most straightforward and may in fact simplify some other parts of our code.  Option 2 is an interesting idea that I will try to look into when I have more time.

    One thing you might want to consider though is attempt to get a TypeConverter from the Type passed in on the ItemPropertyDefinition, and use that to convert the string entered in the argument to a value of the proper type using ConvertFromString.  I am thinking of code similar to the following:

    // Attempt to get a type converter for the property type.
    var converter = TypeDescriptor.GetConverter(PropertyType);
    if (converter != null)
    {
        // Convert the argument to an object of the same type as this property,
        // and hold on to it as an IComparable.
        var nativeObject = converter.ConvertFromString(argument);
        comparable = nativeObject as IComparable;
    }

    In this code sample I get the native value as an IComparable, but you may not need to do this for your implementation.  (This code is from the filtering system I had implemented before using the RadDataFilter and it worked very well.  I am in the process of migrating to the RadDataFIlter for the boolean functionality it offers.)

    Thoughts?

    Mark
  5. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 10 Feb 2011 Link to this post

    Hi Mark,

    The problem with that approach would be that depending on the underlying Type a Factory creates a default editor -- RadDateTimePicker for DateTime's, RadMaskedTextBox for numeric type, RadComboBox for enums, StringFilterEditor for string so forth. So we are in fact not dealing with string all the time.

    So the problem is that the value is double you will get a RadMaskedTextBox with the appropriate mask and the values the user enters are already numbers, not strings.

    Just for that purpose I have developed the Custom Filter Editors functionality. It allows the developer to provide his own editor. So this editor could be something as simple as an UserControl with a TextBox. This user control can have a ceratin DependencyProperty of type double for example, which will be bound to the Value property of the its DataContext, i.e. the view model.

    With this approach the end user can be presented with any kind of UI, i.e. TextBox, Calendar, Slider, you name it and this will not affect the underlying actual value which can be double, string, etc. Something like this:

    <DataTemplate x:Key="QuantityFilterEditorTemplate">
                    <telerik:RadSlider Value="{Binding Value, Mode=TwoWay, FallbackValue=0}"
                                       Width="100"
                                       TickPlacement="BottomRight"/>
                </DataTemplate>

    Value is the property on the view model that will accept the value from the editor.

    Or the other thing you can do is simply place a plain old TextBox in the DataTemplate and bind its Text to the Value property of the view model with a Converter. In this way the user will be entering the human readable string and your IValueConverter will make them doubles before passing them to the FilterDescriptor.Value.

    I hope this helps. Let me know if you have any other questions.

    All the best,
    Ross
    the Telerik team
    Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
  6. Mark
    Mark avatar
    44 posts
    Member since:
    Jun 2009

    Posted 10 Feb 2011 Link to this post

    Hi Ross,

    Yes - this makes perfect sense. 

    Thank again,
    Mark.
Back to Top
UI for WPF is Visual Studio 2017 Ready