Create custom filter based on property Type

7 posts, 0 answers
  1. ianr
    ianr avatar
    14 posts
    Member since:
    Mar 2010

    Posted 26 Mar 2012 Link to this post

    Hi,

    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.
  2. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 26 Mar 2012 Link to this post

    Hi,

    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.

    Kind regards,
    Ross
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. UI for WPF is Visual Studio 2017 Ready
  4. ianr
    ianr avatar
    14 posts
    Member since:
    Mar 2010

    Posted 26 Mar 2012 Link to this post

    Hi,

    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.
  5. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 26 Mar 2012 Link to this post

    Hi,

    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.

    All the best,
    Ross
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  6. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 26 Mar 2012 Link to this post

    Hello,

    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.

    Greetings,
    Ross
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  7. ianr
    ianr avatar
    14 posts
    Member since:
    Mar 2010

    Posted 26 Mar 2012 Link to this post

    Hi Ross,

    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.
  8. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 26 Mar 2012 Link to this post

    Hi,

    I see your point, but I am afraid that this Type check cannot be turned off.

    All the best,
    Ross
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Back to Top
UI for WPF is Visual Studio 2017 Ready