简体   繁体   English

如何在.NET 4中覆盖动态对象的PropertyDescriptor.GetValue和PropertyDescriptor.SetValue

[英]How to override PropertyDescriptor.GetValue and PropertyDescriptor.SetValue for dynamic object in .NET 4

We are using DynamicObject for dynamic properties creation, but then we want to use PropertyGrid to show this properties and edit them. 我们使用DynamicObject进行动态属性创建,但之后我们要使用PropertyGrid来显示这些属性并对其进行编辑。

Firstly, I found this article, and this one . 首先,我发现这个文章,而这一个 I try to use second article code, but in more generic fashion, basically to replace all methods names constants with variables. 我尝试使用第二篇文章代码,但以更通用的方式,基本上用变量替换所有方法名称常量。 But the problem is that VS2010 can't find CSharpGetMemberBinder type. 但问题是VS2010找不到CSharpGetMemberBinder类型。

Does someone know how to replace it? 有人知道如何更换它吗? or what is the best approach? 或者最好的方法是什么?

Instead of using that article's Helper class (which is outdated), you can simply cast to IDictionary and set / retrieve the values: 您可以简单地转换为IDictionary并设置/检索值,而不是使用该文章的Helper类(已过时)。

        public override object GetValue(object component)
        {
            if (_owner != component) throw new InvalidOperationException("GetValue can only be used with the descriptor's owner.");
            //return DynamicHelper.GetValue(component, _propertyName);
            return ((IDictionary<String, object>)component)[_propertyName];
        }

        public override void SetValue(object component, object value)
        {
            if (_owner != component) throw new InvalidOperationException("SetValue can only be used with the descriptor's owner.");
            OnValueChanged(component, EventArgs.Empty);
            //DynamicHelper.SetValue(component, _propertyName, value);
            ((IDictionary<String, object>)component)[_propertyName] = value;
        }

Edit: This may only work in the case of ExpandoObjects, which was what the article was using.. if you created your own dynamic class with a different backing, you may need to change this. 编辑:这可能仅适用于ExpandoObjects,这是文章正在使用的..如果您创建自己的动态类具有不同的支持,您可能需要更改它。

You can use the open source framework Dynamitey it lets you invoke dynamic properties of any IDynamicMetaObjectProvider by string name. 您可以使用开源框架Dynamitey,它允许您通过字符串名称调用任何 IDynamicMetaObjectProvider的动态属性。

    public override object GetValue(object component)
    {
        return Dyanmic.InvokeGet(component,propertyName);
    }

    public override void SetValue(object component, object value)
    {
         Dyanmic.InvokeSet(component,propertyName, value);
    }

It should be something like: 它应该是这样的:

CallSiteContainer.getLengthSite = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None,
    "Length",
    typeof(Program),
    new CSharpArgumentInfo[] {
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
    }));

and the associated set would be something like: 和相关的集合将是这样的:

CallSiteContainer.setLengthSite = CallSite<Func<CallSite, object, object, object>>.Create(Binder.SetMember(CSharpBinderFlags.None,
    "Length",
    typeof(Program),
    new CSharpArgumentInfo[] {
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)
    }));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM