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

发布于 2024-09-30 14:26:19 字数 444 浏览 5 评论 0原文

我们使用DynamicObject 进行动态属性创建,但随后我们想要使用PropertyGrid 来显示此属性并编辑它们。

首先,我找到了这篇文章,以及这篇一个。我尝试使用第二篇文章的代码,但以更通用的方式,基本上用变量替换所有方法名称常量。但问题是VS2010找不到CSharpGetMemberBinder类型。

有人知道如何更换吗?或者最好的方法是什么?

We are using DynamicObject for dynamic properties creation, but then we want to use PropertyGrid to show this properties and edit them.

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.

Does someone know how to replace it? or what is the best approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清旖 2024-10-07 14:26:19

您可以简单地转换为 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;
        }

编辑:这可能仅适用于 ExpandoObjects 的情况,这就是本文所使用的。如果您创建了您自己的动态类具有不同的支持,您可能需要更改它。

Instead of using that article's Helper class (which is outdated), you can simply cast to IDictionary and set / retrieve the values:

        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.

余厌 2024-10-07 14:26:19

您可以使用开源框架Dynamitey,它可以让您调用任何<的动态属性/em> 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);
    }

You can use the open source framework Dynamitey it lets you invoke dynamic properties of any IDynamicMetaObjectProvider by string name.

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

    public override void SetValue(object component, object value)
    {
         Dyanmic.InvokeSet(component,propertyName, value);
    }
潇烟暮雨 2024-10-07 14:26:19

它应该类似于:

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

关联的集合类似于:

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)
    }));

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)
    }));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文