Hi,
we want to bind a RadGridView to a collection of objects that implement DynamicObject. However, we don't want to bind to the dynamic properties, but only classical properties (e.g. the Name property in the following example).
However, the RadGridView only tries to bind to the dynamic members and throws exceptions if the dynamic member is not found. It does not even check if there is a normal property with the same name. This affects not only binding, but also sorting, grouping and filtering.
The typical behavior in WPF (e.g. when using a binding) and C# (when using the dynamic keyword) is to check for normal properties first! This should be the same in the RadGridView.
Alex
we want to bind a RadGridView to a collection of objects that implement DynamicObject. However, we don't want to bind to the dynamic properties, but only classical properties (e.g. the Name property in the following example).
public class MyDynamicObject : DynamicObject
{
public string Name { get; set; }
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
return base.TrySetMember(binder, value);
}
}
However, the RadGridView only tries to bind to the dynamic members and throws exceptions if the dynamic member is not found. It does not even check if there is a normal property with the same name. This affects not only binding, but also sorting, grouping and filtering.
The typical behavior in WPF (e.g. when using a binding) and C# (when using the dynamic keyword) is to check for normal properties first! This should be the same in the RadGridView.
Alex
5 Answers, 1 is accepted
0
Hi,
We have a help article that illustrates certain modifications for the DynamicObject implementation that are needed in such scenarios: Have mixed CLR and DLR properties. Can you please have a look at it and tell us whether this approach works for you?
Regards,
Ivan Ivanov
Telerik
We have a help article that illustrates certain modifications for the DynamicObject implementation that are needed in such scenarios: Have mixed CLR and DLR properties. Can you please have a look at it and tell us whether this approach works for you?
Regards,
Ivan Ivanov
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
0
Alexander
Top achievements
Rank 1
answered on 19 Jan 2015, 01:40 PM
Hello Ivan,
thanks for your answer.
I have to admit that I absolutely do not like this solution (even though it would be possible), as this simply is boilerplate code and I loose type safety and the possibility of simply renaming these properties. Is there a reason why you don't follow the typical behavior of C# and WPF?
Alex
thanks for your answer.
I have to admit that I absolutely do not like this solution (even though it would be possible), as this simply is boilerplate code and I loose type safety and the possibility of simply renaming these properties. Is there a reason why you don't follow the typical behavior of C# and WPF?
Alex
0
Hello,
In order to achieve better performance we use the data binding mechanism only as last available option, as it is quite slow. Basically, we use the .Net expression API to retrieve property values, building member access lambda functions. However, we have separate logic for CLR and DLR properties, so the things need to be tweaked a little, if one wants to combine them.
Regards,
Ivan Ivanov
Telerik
In order to achieve better performance we use the data binding mechanism only as last available option, as it is quite slow. Basically, we use the .Net expression API to retrieve property values, building member access lambda functions. However, we have separate logic for CLR and DLR properties, so the things need to be tweaked a little, if one wants to combine them.
Regards,
Ivan Ivanov
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
0
Alexander
Top achievements
Rank 1
answered on 23 Jan 2015, 08:23 AM
Yes, I debugged into your source code and saw that you use some Expression builder:
At the moment, I find it somewhat inconsistent that when you select "AutoGenerateColumns", the columns for both CLR and DLR properties are generated, however only DLR properties are considered to get the value. Particularly, GetDynamicMemberNames does not enumnerate the CLR properties - why do you rely that these will be handled by TryGetMember?
My proposal points into the direction that your DynamicPropertyAccessExpressionBuilder should check if there is a CLR property with the given name and fall back to the normal property access before building the pure dynamic expression. Unfortunately, there does not seem to be a way to hook into this mechanism from user side. It would be nice if this could be improved on your side. If you don't want to break existing code, then maybe this could be guarded by some setting?
Alex
if (elementType.IsDynamic())
{
return new DynamicPropertyAccessExpressionBuilder(elementType, memberName, memberType);
}
return new PropertyAccessExpressionBuilder(elementType, memberName, memberType);
At the moment, I find it somewhat inconsistent that when you select "AutoGenerateColumns", the columns for both CLR and DLR properties are generated, however only DLR properties are considered to get the value. Particularly, GetDynamicMemberNames does not enumnerate the CLR properties - why do you rely that these will be handled by TryGetMember?
My proposal points into the direction that your DynamicPropertyAccessExpressionBuilder should check if there is a CLR property with the given name and fall back to the normal property access before building the pure dynamic expression. Unfortunately, there does not seem to be a way to hook into this mechanism from user side. It would be nice if this could be improved on your side. If you don't want to break existing code, then maybe this could be guarded by some setting?
Alex
0
Hi,
You are right. This check can be done in accordance to the member specificity (CLR or DLR), instead of the declaration type. And this matter is closely related to your question about GetDynamicMemberNames and CLR properties. Actually, we create different PropertyDescriptors for the CLR and DLR properties, and on this level we can easily distinct them from each other. DynamicPropertyDescriptors are created for each member that GetDynamicMemberNames returns and CLR descriptors are retrieved afterwards.
But deeper in the data engine, the expression builder in particular, we do not work with the descriptors themselves, but only with member names and member types. Thus this distinctive difference gets lost. The problem here lies in the fact that our expression builder engine has been written before we added DLR support. We can certainly improve this by providing this information to the expression builder, but this might not be a trivial change as it may affect the core functionality of several of our controls. Thank you for providing your feedback on this topic. We will consider it for a future improvement of our data engine.
Regards,
Ivan Ivanov
Telerik
You are right. This check can be done in accordance to the member specificity (CLR or DLR), instead of the declaration type. And this matter is closely related to your question about GetDynamicMemberNames and CLR properties. Actually, we create different PropertyDescriptors for the CLR and DLR properties, and on this level we can easily distinct them from each other. DynamicPropertyDescriptors are created for each member that GetDynamicMemberNames returns and CLR descriptors are retrieved afterwards.
if (elementType.IsDynamicMetaObjectProvider())
{
descriptors.AddRange(GetPropertyDescriptorsForDynamicType(collectionView));
}
descriptors.AddRange(TypeDescriptor.GetProperties(elementType).OfType<
PropertyDescriptor
>());
But deeper in the data engine, the expression builder in particular, we do not work with the descriptors themselves, but only with member names and member types. Thus this distinctive difference gets lost. The problem here lies in the fact that our expression builder engine has been written before we added DLR support. We can certainly improve this by providing this information to the expression builder, but this might not be a trivial change as it may affect the core functionality of several of our controls. Thank you for providing your feedback on this topic. We will consider it for a future improvement of our data engine.
Regards,
Ivan Ivanov
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
Eldoir
commented on 22 Jun 2022, 02:02 PM
Top achievements
Rank 2
Iron
Iron
Iron
Hi Ivan, sorry for necroing this but do you have a version number where this is fixed?
Thanks,
Arthur
Dilyan Traykov
commented on 27 Jun 2022, 01:35 PM
Telerik team
Hello Arthur,
As mentioned by Ivan, this improvement will not be straightforward and would require a significant demand for us to proceed with the implementation.
For the time being, we can suggest using the approach from this article that Ivan mentioned earlier or introducing an ICustomTypePovider as suggested by my colleague in this thread (which is actually related to the scenario discussed here).
As mentioned by Ivan, this improvement will not be straightforward and would require a significant demand for us to proceed with the implementation.
For the time being, we can suggest using the approach from this article that Ivan mentioned earlier or introducing an ICustomTypePovider as suggested by my colleague in this thread (which is actually related to the scenario discussed here).