CustomTypeDescriptor / runtime properties

8 posts, 0 answers
  1. Radiation
    Radiation avatar
    13 posts
    Member since:
    Jul 2012

    Posted 05 Nov 2012 Link to this post

    Hi,

    I'm trying to use approach described here (http://www.telerik.com/community/forums/winforms/property-grid/binding-to-datatable.aspx) with wpf RadropertyGrid.

    In my scenario, I have an API that returns list of properties for particular instance. That means that properties are resolved at runtime for particular instance. Each instance can have different properties.
    *property is described as PropertyName (string), PropertyValue (string), PropertyType(enum).

    CustomTypeDescriptor is ideal solution for me. I can map the PropertyType enum to .net types and convert the PropertyValues from strings to strongly-typed values. This way I can benefit from auto generated propertygrid and default editortemplates.

    The only problem is, that wpf RadPropertyGrid invokes TypeDescriptionProvider just with Type, and don't pass object instance as parameter. You should use TypeDescriptor.GetProperties(object instance) instead of TypeDescriptor.GetProperties(Type type).
      [TypeDescriptionProvider(typeof(Mono3DPropertiesTypeDescriptorProvider))]
      public class Mono3DPropertiesWrapper 
      {
        public readonly Monogram.Mono3D.Control Control;
     
        public Mono3DPropertiesWrapper(Monogram.Mono3D.Control control)
        {
          if (control == null)
          {
            throw new ArgumentNullException("control");
          }
          Control = control;
        }
    }
     
     
      public class Mono3DPropertiesTypeDescriptorProvider : TypeDescriptionProvider
      {
        public Mono3DPropertiesTypeDescriptorProvider()
          : base(TypeDescriptor.GetProvider(typeof(Mono3DPropertiesWrapper)))
        {
        }
        public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
        {
            //HERE IS THE PROBLEM: instance IS NULL. CALLSTACK IS BELLOW
          return new Mono3DPropertiesTypeDescriptor(instance);
        }
      }
     
     
     
      public class Mono3DPropertiesTypeDescriptor : CustomTypeDescriptor
      {
        private readonly object instance;
        public Mono3DPropertiesTypeDescriptor(object instance)
        {
          this.instance = instance;
        }
          ...
      }


    In this callstack you can see that you use TypeDescriptor with object's type insead of instance:

    > LayoutDesigner.dll!Monogram.Sport.ShowDesigner.LayoutDesigner.Internals.Mono3DPropertiesWrapper.Mono3DPropertiesTypeDescriptorProvider.GetTypeDescriptor(System.Type objectType, object instance) Line 39 C#
      System.dll!System.ComponentModel.TypeDescriptor.TypeDescriptionNode.DefaultTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetProperties() + 0x4d bytes 
      System.dll!System.ComponentModel.TypeDescriptor.GetProperties(System.Type componentType) + 0x2e bytes 
      Telerik.Windows.Data.dll!Telerik.Windows.Data.ItemPropertyInfoHelper.GetPropertyDescriptors(Telerik.Windows.Data.QueryableCollectionView collectionView) Line 90 + 0x11 bytes C#
      Telerik.Windows.Data.dll!Telerik.Windows.Data.ItemPropertyInfoHelper.CreateItemProperties(Telerik.Windows.Data.QueryableCollectionView collectionView) Line 41 + 0x9 bytes C#
      Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.GetItemProperties() Line 40 + 0x9 bytes C#
      Telerik.Windows.Data.dll!Telerik.Windows.Data.QueryableCollectionView.ItemProperties.get() Line 31 + 0xf bytes C#
      Telerik.Windows.Controls.Data.dll!Telerik.Windows.Controls.RadPropertyGrid.ItemProperties.get() Line 724 + 0x27 bytes C#
      Telerik.Windows.Controls.Data.dll!Telerik.Windows.Controls.RadPropertyGrid.GeneratePropertyDefinitions() Line 747 + 0x9 bytes C#
      Telerik.Windows.Controls.Data.dll!Telerik.Windows.Controls.RadPropertyGrid.RebindPropertyDefinitions(Telerik.Windows.Controls.RadPropertyGrid propertyGrid) Line 667 + 0xb bytes C#
      Telerik.Windows.Controls.Data.dll!Telerik.Windows.Controls.RadPropertyGrid.OnItemPropertyChanged(System.Windows.DependencyObject sender, System.Windows.DependencyPropertyChangedEventArgs args) Line 581 C#
  2. Radiation
    Radiation avatar
    13 posts
    Member since:
    Jul 2012

    Posted 05 Nov 2012 Link to this post

    I found workaround: I just need to derive class from ICustomTypeDescriptor insead of using DataAnnotation.

    However, it should be mentioned in documentation at least. And I see no reason  for not using TypeDescriptor.GetProperties(object instance) instead of TypeDescriptor.GetProperties(Type type).

    There is another issue with type caching (if the runtime properties changed for another instance of the same class), but I solved it by setting null value to the RadPropertyGrid.Item just before setting the class instance.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1128 posts

    Posted 06 Nov 2012 Link to this post

    Hi Andrej,

     I am glad to hear that you have found a workaround. We will need some more time to investigate the cause of this behavior. I will get back to you as soon as we are ready with our research. As for the caching issue, it has been reported recently, so we have disabled the default caching for dynamic types with today's IB. A proper workaround with the previous version would be to set RadPropertyGrid's EnableEditorsCaching to false.

    Greetings,
    Ivan Ivanov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  5. Radiation
    Radiation avatar
    13 posts
    Member since:
    Jul 2012

    Posted 14 Jan 2013 Link to this post

    My suggestion is to enable caching for types with custom TypeDescriptor based on TypeDescriptor.GetClassName(). This makes more sense than disabling if it can be disabled explicitly.
  6. Radiation
    Radiation avatar
    13 posts
    Member since:
    Jul 2012

    Posted 14 Jan 2013 Link to this post

    My suggestion is to enable caching for types with custom TypeDescriptor based on TypeDescriptor.GetClassName(). This makes more sense than disabling it while it can be disabled explicitly.
  7. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1128 posts

    Posted 17 Jan 2013 Link to this post

    Hello,

    This seems like a reasonable approach. We will test it. Thank you.

    Greetings,
    Ivan Ivanov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  8. Magnus
    Magnus avatar
    3 posts
    Member since:
    Feb 2015

    Posted 08 Apr 2015 in reply to Ivan Ivanov Link to this post

    Hi,

    It seems like RadPropertyGrid is still calling TypeDescriptor.GetProperties(Type type) instead of GetProperties(object instance) as Radiation mentioned above. Are you going to fix this or can you explain this behaviour?

     

  9. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 10 Apr 2015 Link to this post

    Hi,

    It is indeed still in that way. Would you please share a bit more information on what your specific scenario is? Since this is an old thread related to CustomTypeDescriptor, you can also open a new support ticket and share some more detailed information on the result you are trying to achieve.

    Regards,
    Dimitrina
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
Back to Top
UI for WPF is Visual Studio 2017 Ready