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?
What's the best way to go about this? Is DynamicObject suitable?
4 Answers, 1 is accepted
0
Hello,
Ivan Ivanov
the Telerik team
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
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
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.
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
; }
}