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

Bind to "normal" properties in dynamic object

5 Answers 219 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Alexander
Top achievements
Rank 1
Alexander asked on 16 Jan 2015, 09:13 AM
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).

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

Sort by
0
Ivan Ivanov
Telerik team
answered on 19 Jan 2015, 01:05 PM
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
 

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
0
Ivan Ivanov
Telerik team
answered on 21 Jan 2015, 04:26 PM
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
 

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:


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
Ivan Ivanov
Telerik team
answered on 24 Jan 2015, 12:21 PM
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.
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
Top achievements
Rank 2
Iron
Iron
Iron
commented on 22 Jun 2022, 02:02 PM

Hi Ivan, sorry for necroing this but do you have a version number where this is fixed?
Thanks,
Arthur

Dilyan Traykov
Telerik team
commented on 27 Jun 2022, 01:35 PM

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).
Tags
GridView
Asked by
Alexander
Top achievements
Rank 1
Answers by
Ivan Ivanov
Telerik team
Alexander
Top achievements
Rank 1
Share this question
or