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

DynamicObject property types

4 Answers 278 Views
PropertyGrid
This is a migrated thread and some comments may be shown as answers.
Jerome
Top achievements
Rank 1
Jerome asked on 01 Feb 2013, 01:18 AM
Hello. I'm trying to figure out the proper way to provide editing for a collection of name/type/value things. I was hoping to use DynamicObject, and expose dynamic properties for the properties to be edited. DynamicObject however, as far as I can tell, has no real way to expose more than a member name to consumers (such as RadPropertyGrid.) So, I don't know how to expose the TYPE of the propert to RadPropertyGrid.

What's the best way to go about this? Is DynamicObject suitable?

4 Answers, 1 is accepted

Sort by
0
Ivan Ivanov
Telerik team
answered on 05 Feb 2013, 03:59 PM
Hello,

RadPropertyGrid supports such scenarios with some minor customizations. May, I ask you to send us a small project that illustrates your business object declaration through a support ticket and I will prepare a demo project for you?

Kind regards,
Ivan Ivanov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Chris
Top achievements
Rank 1
answered on 06 Nov 2015, 05:38 PM

Ivan,

     Could you send me the demo project as well. I am trying to do the same thing. Thank you.

0
Ivan Ivanov
Telerik team
answered on 11 Nov 2015, 05:20 PM
Hi,

I prepared a sample project with RadPropertyGrid with dynamic properties. You can use it as a starting point if you have any further questions.

Regards,
Ivan Ivanov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Chris
Top achievements
Rank 1
answered on 11 Nov 2015, 05:53 PM
Thank you Ivan.

For anyone else that is pursuing this approach, here is the code that is working for me.

private sealed class MyDynObject : DynamicObject, ICustomTypeDescriptor, INotifyPropertyChanged
  {
    private class OrderedProperty
    {
      public IProperty Property { get; set; }
      public int Order { get; set; }
    }
  
    private readonly Dictionary<string, OrderedProperty> dynamicProperties
      = new Dictionary<string, OrderedProperty>();
  
    public MyDynObject(ReadOnlyObservableCollection<IProperty> properties)
    {
      for (var i = 0; i < properties.Count; i++)
      {
        var property = properties[i];
        dynamicProperties.Add(property.Name, new OrderedProperty()
        {
          Property = property,
          Order = i
        });
        PropertyChangedEventManager.AddHandler(property, Property_PropertyChanged, nameof(IProperty.Value));
      }
    }
  
    private void Property_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
      if (nameof(IProperty.Value).Equals(e.PropertyName))
      {
        OnPropertyChanged(((IProperty)sender).Name);
      }
    }
  
    public override IEnumerable<string> GetDynamicMemberNames()
    {
      return dynamicProperties.Keys;
    }
  
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
      if (dynamicProperties.ContainsKey(binder.Name))
      {
        result = dynamicProperties[binder.Name].Property.Value;
        return true;
      }
      result = null;
      return false;
    }
  
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
      if (dynamicProperties.ContainsKey(binder.Name))
      {
        dynamicProperties[binder.Name].Property.Value = value;
        OnPropertyChanged(binder.Name);
        return true;
      }
      return false;
    }
  
    #region Implementation of INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
  
    private void OnPropertyChanged(string propertyName)
    {
      if (PropertyChanged == null)
      {
        return;
      }
  
      var eventArgs = new PropertyChangedEventArgs(propertyName);
      PropertyChanged(this, eventArgs);
    }
    #endregion
  
    #region Implementation of ICustomTypeDescriptor
    public AttributeCollection GetAttributes()
    {
      throw new NotImplementedException();
    }
  
    public string GetClassName()
    {
      return GetType().Name;
    }
  
    public string GetComponentName()
    {
      throw new NotImplementedException();
    }
  
    public TypeConverter GetConverter()
    {
      throw new NotImplementedException();
    }
  
    public EventDescriptor GetDefaultEvent()
    {
      throw new NotImplementedException();
    }
  
    public PropertyDescriptor GetDefaultProperty()
    {
      throw new NotImplementedException();
    }
  
    public object GetEditor(Type editorBaseType)
    {
      throw new NotImplementedException();
    }
  
    public EventDescriptorCollection GetEvents()
    {
      throw new NotImplementedException();
    }
  
    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
      throw new NotImplementedException();
    }
  
    public PropertyDescriptorCollection GetProperties()
    {
      var properties = dynamicProperties
          .Select(pair => new DynamicPropertyDescriptor(this,
              pair.Key, pair.Value.Property.ValueType, GetAttributes(pair.Value)));
      return new PropertyDescriptorCollection(properties.Cast<PropertyDescriptor>().ToArray());
    }
  
    public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
      throw new NotImplementedException();
    }
  
    public object GetPropertyOwner(PropertyDescriptor pd)
    {
      throw new NotImplementedException();
    }
  
    private Attribute[] GetAttributes(OrderedProperty orderedProperty)
    {
      var attributes = new Attribute[2];
      attributes[0] = new DisplayAttribute
      {
        Name = orderedProperty.Property.Name,
        Description = orderedProperty.Property.Description,
        GroupName = orderedProperty.Property.GroupName,
        Order = orderedProperty.Order
      };
      attributes[1] = new ReadOnlyAttribute(orderedProperty.Property.IsReadOnly);
      return attributes;
    }
    #endregion
  
  
  
  
    private class DynamicPropertyDescriptor : PropertyDescriptor
    {
      private readonly MyDynObject model;
  
      public DynamicPropertyDescriptor(MyDynObject model,
          string propertyName, Type propertyType, Attribute[] propertyAttributes)
          : base(propertyName, propertyAttributes)
      {
        this.model = model;
        PropertyType = propertyType;
      }
  
      public override bool CanResetValue(object component)
      {
        return true;
      }
  
      public override object GetValue(object component)
      {
        return model.dynamicProperties[Name].Property.Value;
      }
  
      public override void ResetValue(object component)
      {
      }
  
      public override void SetValue(object component, object value)
      {
        model.dynamicProperties[Name].Property.Value = value;
      }
  
      public override bool ShouldSerializeValue(object component)
      {
        return false;
      }
  
      public override Type ComponentType => typeof(MyDynObject);
  
      public override bool IsReadOnly => model.dynamicProperties[Name].Property.IsReadOnly;
  
      public override Type PropertyType { get; }
    }
  }
 
  
 
public interface IProperty : INotifyPropertyChanged
  {
    string Name { get; }
  
    object Value { get; set; }
  
    Type ValueType { get; }
  
    string Description { get; }
  
    bool IsReadOnly { get; }
  
    string GroupName { get; }
  }
Tags
PropertyGrid
Asked by
Jerome
Top achievements
Rank 1
Answers by
Ivan Ivanov
Telerik team
Chris
Top achievements
Rank 1
Share this question
or