Как переопределить PropertyDescriptor.GetValue и PropertyDescriptor.SetValue для динамического объекта в .NET 4 - PullRequest
5 голосов
/ 05 ноября 2010

Мы используем DynamicObject для создания динамических свойств, но затем мы хотим использовать PropertyGrid, чтобы показать эти свойства и отредактировать их.

Во-первых, я нашел эту статью и эту одну . Я пытаюсь использовать код второй статьи, но в более общем виде, в основном, чтобы заменить все константы имен методов на переменные. Но проблема в том, что VS2010 не может найти тип CSharpGetMemberBinder.

Кто-нибудь знает, как его заменить? или какой подход лучше?

Ответы [ 3 ]

1 голос
/ 21 апреля 2011

Вы можете использовать фреймворк с открытым исходным кодом Dynamitey , который позволяет вам вызывать динамические свойства any 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);
    }
1 голос
/ 05 ноября 2010

Вместо использования класса Helper этой статьи (который устарел), вы можете просто привести к IDictionary и установить / получить значения:

        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,именно это и использовала статья ... если вы создали собственный динамический класс с другой поддержкой, возможно, вам придется изменить это.

0 голосов
/ 21 апреля 2011

Это должно быть что-то вроде:

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