Привязка DynamicObject к DataGrid с автоматической генерацией столбцов? - PullRequest
8 голосов
/ 19 марта 2010

Я все еще экспериментирую с DynamicObjects. Теперь мне нужна некоторая информация: я пытаюсь связать объект, наследуемый от DynamicObject, с WPF DataGrid (не Silverlight).

Как получить DataGrid для автоматического создания его столбцов из доступных общедоступных свойств объекта, которые обычно создаются во время выполнения? Это возможно на самом деле?

Ответы [ 2 ]

10 голосов
/ 14 марта 2011

Не существует единого способа запроса динамических свойств, обычно ожидается, что вы знаете их заранее. С DynamicObject разработчики могут переопределить GetMemberNames, и это обычно дает вам свойства, однако это действительно предназначено для отладки, потому что нет требования, чтобы он предоставлял все свойства. В противном случае, если это ваш DynamicObject, вам просто нужно написать собственный метод, чтобы получить свойства, основанные на вашей динамической реализации. Например, ExpandoObject позволяет запрашивать все свойства с помощью интерфейса IDictionary.

Поэтому, когда у вас есть способ получить ваши свойства, вам нужно сообщить DataGrid. К сожалению, с DataGrid проблема с реализацией ICustomTypeDescriptor, чтобы сообщить DataGrid о ваших свойствах, заключается в том, что DataGrid получает TypeDescriptors с использованием Type, а не экземпляра, что является проблемой для динамических объектов, однако реализует ITypedList в коллекции DynamicObjects. будет работать с очень маленькой ошибкой, если вы не реализуете неуниверсальный интерфейс IList в своей коллекции, он будет удален до того, как будет проверен на ITypeList.

Итак, в итоге, реализуйте коллекцию с ITypedList и IList. С ITypedList вернуть null для GetListName и просто реализовать GetItemProperties(PropertyDescriptor[] listAccessors); Игнорируйте listAccessors и возвращайте PropertyDescriptorCollection PropertyDescriptors для каждого члена, названного на основе наиболее представленного экземпляра динамического объекта в вашем списке (скорее всего, только первый объект). Вам необходимо реализовать подкласс PropertyDescriptor, простой и общий способ получения значения Get / Set - это использование инфраструктуры с открытым исходным кодом Dynamitey

using System;
using System.ComponentModel;
using Dynamitey;
public class DynamicPropertyDescriptor:PropertyDescriptor
{
        public DynamicPropertyDescriptor(string name) : base(name, null)
        {
        }

        public override bool CanResetValue(object component)
        {
            return false;
        }

        public override object GetValue(object component)
        {
           return Dynamic.InvokeGet(component, Name);
        }

        public override void ResetValue(object component)
        {

        }

        public override void SetValue(object component, object value)
        {
            Dynamic.InvokeSet(component, Name, value);
        }

        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }

        public override Type ComponentType
        {
            get { return typeof(object); }
        }

        public override bool IsReadOnly
        {
            get { return false; }
        }

        public override Type PropertyType
        {
            get
            {
                return typeof (object);
            }
        }
}
2 голосов
/ 20 августа 2010

Я думаю, DataGrid использует TypeDescriptor, чтобы получить свойства объекта для создания столбцов. Таким образом, вы сможете достичь этого, если ваш DynamicObject реализует ICustomTypeDescriptor. Реализуйте метод GetProperties, чтобы он возвращал динамические свойства вашего объекта.

...