Thursday 6 January 2011

Implementing ICustomTypeDescriptor for dynamic properties

I have recently had a requirement to bind a grid view to a record object that could have any number of properties that can be added and removed at runtime. This was to allow a user to add a new column to a result set to enter an additional set of data.

This can be achieved by having each data 'row' as a dictionary with the key being the property name and the value being a string or a class that can store the value of the property for the specified row. Of course having a List of Dictionary objects will not be able to be bound to a grid. This is where the ICustomTypeDescriptor comes in.

By creating a wrapper class for the Dictionary and making it adhere to the ICustomTypeDescriptor interface the behaviour for returning properties for an object can be overridden.

Take a look at the implementation of the data 'row' class below:


Note: In the GetProperties method I Could Cache the PropertyDescriptors once read for performance but as I'm adding and removing columns at runtime I always want them rebuilt

You will also notice in the GetProperties method that the Property Descriptors added for the dictionary entries are of type TestResultPropertyDescriptor. This is a custom Property Descriptor class that manages how properties are set and retrieved. Take a look at the implementation below:



The main properties to look at on this class are GetValue and SetValue. Here you can see the component being casted as a dictionary and the value of the key inside it being Set or retrieved. Its important that the dictionary in this class is the same type in the Row wrapper class otherwise the cast will fail. When the descriptor is created the key (property name) is passed in and is used to query the dictionary to get the correct value.

22 comments:

  1. @Alen - looks like the syntax highlighter server is down so its not showing code samples. If you leave your email address ill send over the full post. Ill delete the post with you email afterwards :)

    ReplyDelete
  2. Great post. Please could you send me full code sample?.

    I sent an email to you

    Thanks.

    ReplyDelete
  3. Sorry, I have not found your email to contact you.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hi Alberto,

    I think I have found the three classes. Do you have somewhere I can send them?

    Nathan

    ReplyDelete
  6. Hi,

    I have sent to you an email.

    Thanks for all

    ReplyDelete
  7. Can using the System.Dynamic expando solve this problem is a simple and "as elegant" way?

    ReplyDelete
  8. Hi Anon,

    Not sure, I have not heard of, or used it. Do you have a link?

    ReplyDelete
  9. plase send me the code sample for it

    ReplyDelete
    Replies
    1. Hi Sashi,

      I'm afraid I cant send the project as it contains confidential information. However, the code samples above were taken from the project and the namespaces etc. changed so it should be everything you need.

      Best regards,

      Nathan

      Delete
  10. Hello can i get the complete code to implement this type of Scenario you can send to hakeem.abdul.mohammed@gmail.com

    ReplyDelete
    Replies
    1. I'm afraid I cant send the project as it contains confidential information. However, the code samples above were taken from the project and the namespaces etc. changed so it should be everything you need.

      Best regards,

      Nathan

      Delete
  11. Hi WraithNath, I would like take a look on the complete code. Can you send to me a sample too? Thanks

    ReplyDelete
  12. Nice code - I would also like to see the completed code.

    Thanks.

    ReplyDelete
  13. Replies
    1. Check you don't have any browser extensions blocking SyntaxHighlighter.

      http://alexgorbatchev.com/SyntaxHighlighter

      Delete
  14. Would it be possible to upload the 3 classes you have mentioned to somewhere like Github to get a better understanding of your cound

    ReplyDelete