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

RadDataFilter and Value Converters

4 Answers 132 Views
DataFilter
This is a migrated thread and some comments may be shown as answers.
Mark
Top achievements
Rank 1
Mark asked on 08 Feb 2011, 11:03 PM
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.

4 Answers, 1 is accepted

Sort by
0
Accepted
Rossen Hristov
Telerik team
answered on 09 Feb 2011, 03:03 PM
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>>
0
Mark
Top achievements
Rank 1
answered on 09 Feb 2011, 06:17 PM
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
0
Rossen Hristov
Telerik team
answered on 10 Feb 2011, 09:22 AM
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>>
0
Mark
Top achievements
Rank 1
answered on 10 Feb 2011, 05:09 PM
Hi Ross,

Yes - this makes perfect sense. 

Thank again,
Mark.
Tags
DataFilter
Asked by
Mark
Top achievements
Rank 1
Answers by
Rossen Hristov
Telerik team
Mark
Top achievements
Rank 1
Share this question
or