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

CustomTypeDescriptor / runtime properties

7 Answers 426 Views
PropertyGrid
This is a migrated thread and some comments may be shown as answers.
Radiation
Top achievements
Rank 1
Radiation asked on 05 Nov 2012, 12:13 PM
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#

7 Answers, 1 is accepted

Sort by
0
Radiation
Top achievements
Rank 1
answered on 05 Nov 2012, 03:25 PM
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.
0
Ivan Ivanov
Telerik team
answered on 06 Nov 2012, 05:02 PM
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.

0
Radiation
Top achievements
Rank 1
answered on 14 Jan 2013, 11:33 AM
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.
0
Radiation
Top achievements
Rank 1
answered on 14 Jan 2013, 11:35 AM
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.
0
Ivan Ivanov
Telerik team
answered on 17 Jan 2013, 04:17 PM
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.

0
Magnus
Top achievements
Rank 2
answered on 08 Apr 2015, 07:01 AM

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?

 

0
Dimitrina
Telerik team
answered on 10 Apr 2015, 08:54 AM
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.

 
Tags
PropertyGrid
Asked by
Radiation
Top achievements
Rank 1
Answers by
Radiation
Top achievements
Rank 1
Ivan Ivanov
Telerik team
Magnus
Top achievements
Rank 2
Dimitrina
Telerik team
Share this question
or