I have used the EditorTemplateRules to created custom filters for various properties based on their name (i.e. combo boxes populated with appropriate data).
What I would like to do now is create a rule based on property type rather than property name. I want all properties of type DateTime (or DateTime?) to use a custom control.
Is this possible?
Thanks.
6 Answers, 1 is accepted
Of course. You are free to create any kind of DataTemplateSelector.
You can get all the information required in the SelectTemplate method by casting item to ItemPropertyDefinition just like in our example. This ItemPropertyDefinition thing contains all relevant information that you need, including the Type.
I hope this helps.
Ross
the Telerik team
Thanks for the quick reply. I got it working using an EditorTemplateSelector: in the override DataTemplate SelectTemplate method, if the property definition MemberType is a date, then I select the custom date editor template from the list of EditorTemplateRules and return it. This works fine.
However, I now have a second issue which seems trickier. My custom date control will allow the user to select a date (via a RadDateTimePicker) or select from a number of options in a drop down (e.g. Today, This Week, etc.). I want to store the selection in a string field within the FilterDescriptor. So, I would store possible values of; '2012-03-26', 'today', 'thisweek', etc. These will then be used to build a linq query.
The custom control has a dependency property of type string called 'DateText', which are set by the control to the values above. This is bound to the Value property of the filterdescriptor via the DataTemplate:
<DataTemplate x:Uid="DataTemplate_14" x:Key="DateTemplate"> <controls:DateFilter MinWidth="150" DateText="{Binding Value, Mode=TwoWay}" /> </DataTemplate>
However, the value of the DateText dependency property is only being set properly from the code-behind of the control if it is a valid date (e.g. the '2012-03-26' value). As the dependency property type is string, and the filterdescriptor Value property is object this problem was unexpected.
I suspect that in the underlying telerik classes implementation, the Value property is inspected along with the MemberType property (which in my case is DateTime or DateTime?) and rejected if it does not match.
So, my question is: is this what is happening, and is there a way around this? Although the MemberType may be a DateTime type, I want to be able to store any string in the Value property.
Thanks.
You are right and that is normal. When the underlying property is a DateTime, you have to supply a DateTime as the Value of the FilterDescriptor since .NET is a strongly typed platform.
Unfortunately, you can't write a LINQ statement in .NET like this:
var result = customers.Where(customer.HireDate == "yesterday"), if HireDate is a DateTime property. This will result in an error.
If you want to filter by strings such as 'yesterday' and 'today' you will have to solve this problem in your view model. You will have to expose a new string property on your business object and make RadDataFilter work with this string property instead of the DateTime one. From RadDataFilter's point of view, this will be just a string filter on a string property -- it does not care what is written inside it. It simply builds LINQ statements as the one above at runtime, compiles and executes them against the source data. It will not have any semantic knowledge about what the "2012-03-26" and "yesterday" string mean -- they are simply strings and that's it.
Once these strings "arrive" in your view model, you can process them (i.e. parse, tokenize, you name it) and forward them to the "real" DateTime property of accordingly. Business logic should belong in the business layer, i.e. your business object -- not the UI layer where RadDataFilter operates. I will not mention the huge benefit of unit testing if you weave this logic in your business object class. You will not need a RadDataFilter to test that your business object class can successfully translate the string yesterday to the date 25.03.2012. But that is a topic for another discussion.
I hope this makes sense.
Ross
the Telerik team
OR...
If you want to do comparison filtering such as IsGreaterThan and so on, you will have to keep the DateTime property approach. What you can do is make your custom filter editor smart enough, so that when the user selects Yesterday, it will output a real .NET DateTime for yesterday. But it has to be a DateTime, i.e. the FilterDescriptor.Value should get a DateTime in case the property is DateTime because of the LINQ query that we build.
The bottom-line is that your editor should produce values that are of the same type as the property you are filtering on. Everything else will result in an error since there is no auto-magical way to convert values like that.
I hope this helps.
Ross
the Telerik team
Thanks - that's what I suspected.
The queries that I am building are actually saved to the database and executed when required. The 'code word' values such as 'today' would be converted by the query builder into actual dates or date ranges for the dynamic linq-to-entities query.
Therefore, the value for 'today' would always be converted to the current system date before being used in the query. The column the filter value is stored in is nvarchar, so I had thought with the filter descriptor property being object, I could store whatever I liked then have the query building logic translate it.
I'm not using the data filter to perform in-memory filtering (e.g. against a data grid) but rather as the UI for the query editing, so I had hoped that if the filter descriptor classes were rejecting the value update based on the datatype of the property being filtered, I could just turn that validation off in some way. If not, it looks like I will have to go for additional properties on the objects or encode the options as dates in some way.
Thanks for your help,
Regards,
Ian.
I see your point, but I am afraid that this Type check cannot be turned off.
All the best,Ross
the Telerik team