Domanda

Sono ancora sperimentando con DynamicObjects. Ora ho bisogno di alcune informazioni: Sto cercando di associare un oggetto che eredita dalla DynamicObject ad un WPF DataGrid (non Silverlight).

Come faccio ad avere il controllo DataGrid per creare automaticamente le sue colonne dalle proprietà pubbliche disponibili dell'oggetto che sono tipicamente generati in fase di esecuzione? È quello possibile in realtà?

È stato utile?

Soluzione

Non c'è modo uniforme per interrogare le proprietà dinamiche, generalmente ci si aspetta che li conosci prima del tempo. Con DynamicObject, gli esecutori possono annullare GetMemberNames e che in genere ti dà le proprietà, tuttavia è davvero significava per il debug perché non v'è alcun obbligo che forniscono tutte le proprietà. In caso contrario, se è il proprio DynamicObject non resta che scrivere il proprio metodo per ottenere le proprietà, sulla base di implementazione dinamica. Per esempio ExpandoObject ti permette di interrogare tutte le proprietà utilizzando l'interfaccia IDictionary.

Quindi, una volta che hai un modo per ottenere le proprietà è necessario dire al DataGrid. Purtroppo con un DataGrid, il problema di attuare ICustomTypeDescriptor a dire il DataGrid sulle tue proprietà è che DataGrid ottiene i TypeDescriptors utilizzando il non Type dell'istanza, che è un problema per gli oggetti dinamici, tuttavia attuazione ITypedList sulla raccolta di DynamicObjects funzionerà con il molto piccola Gotcha di se non si implementa l'interfaccia IList non generico sulla vostra collezione, sarà spogliato fuori prima che arrivi al punto in cui si verifica la presenza di ITypeList.

Quindi, in sintesi, implementare una Collezione con ITypedList e IList. Con nullo ritorno ITypedList per GetListName e solo implementare GetItemProperties(PropertyDescriptor[] listAccessors); Ignora listAccessors e restituire un PropertyDescriptorCollection di PropertyDescriptors per ogni membro nominato sulla base della miglior rappresentato istanza di oggetto dinamico nel tuo elenco (molto probabilmente solo il primo oggetto). Tu devi implementare una sottoclasse di PropertyDescriptor, un modo semplice e generale alla / Set valore di ottenere è di utilizzare il framework opensource 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);
            }
        }
}

Altri suggerimenti

Credo che la DataGrid utilizza TypeDescriptor per ottenere le proprietà degli oggetti per creare le colonne. Così si dovrebbe essere in grado di raggiungere questo obiettivo se il vostro DynamicObject implementa ICustomTypeDescriptor. Implementare il metodo GetProperties in modo che restituisca le proprietà dinamiche del vostro oggetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top