2010-06-04 10 views
47

semplicemente esplorando C# 4. Cercando di ottenere la mia testa intorno tutta questa roba dinamica. Scusa se questa domanda è sciocca, nessuna esperienza in questo dominio.Aggiunta di sconosciuti (in fase di progettazione), oggetti da un ExpandoObject

Se ho un ExpandoObject e voglio aggiungere le proprietà pubbliche (con get e set) ad esso in fase di esecuzione, come dovrei andare a farlo?

Per esempio, ho un documentTemplate e un documento, che ha una punta di proprietà verso il documentTemplate. Questo documento contiene alcuni titoli di tag (ad es. Capacità sviluppate tra gli studenti), che dovrebbero essere affrontati durante la creazione del documento (ad esempio concentrazione, memoria ecc.). Quindi, non appena il modello è impostato nel documento, voglio creare una classe, che ha proprietà con gli stessi nomi dei titoli dei tag nel modello, e quindi usando un elemento UI, come il PropertyGrid, posso avere l'utente inserisci i valori dei tag rispetto al tag Titoli.

Grazie per la lettura!

+4

Volevo solo aggiungere che ho letto l'edizione morti-albero di questo articolo su ExpandoObject: http://msdn.microsoft.com/en-us/magazine/ff796227.aspx Non sono sicuro se risponde alle vostre domande, ma è stato un grande primato per me. – Yoopergeek

risposta

92

mi sono chiesto come potrebbe essere possibile aggiungere membri a una classe "al volo" e si avvicinò con questo campione:

using System; 
using System.Collections.Generic; 
using System.Dynamic; 

class Program 
{ 
    static void Main() 
    { 
     dynamic expando = new ExpandoObject(); 
     var p = expando as IDictionary<String, object>; 

     p["A"] = "New val 1"; 
     p["B"] = "New val 2"; 

     Console.WriteLine(expando.A); 
     Console.WriteLine(expando.B); 
    } 
} 

Il punto di questo frammento di codice è che la i membri A e B sono definiti come stringhe letterali (con codifica hard/stringa) e aggiunti tramite l'interfaccia IDictionary di ExpandoObject. Testiamo l'esistenza e i valori delle chiavi (e dimostriamo il concetto) accedendole direttamente e trasmettendole alla console.

+0

Impossibile applicare l'indicizzazione con [] a un'espressione di tipo 'System.Dynamic.ExpandoObject'. Qualche idea? –

+0

@JasonFoglia: Sì. Si prega di postare questo come una domanda e mostrare un po 'di codice compreso l'input e l'output previsto. Possiamo solo immaginare che cosa potrebbe succedere da un commento ... –

3

Sì, ExpandoObject è molto progettato per aggiungere dinamicamente oggetti da una "borsa di proprietà". La nozione di dare una tale proprietà a un getter e setter non è tuttavia supportata. Forse è chiaro se ci pensi un po ': non sarebbe più una proprietà dinamica se sai già cosa dovrebbero fare i getter e setter. Il più vicino possibile è l'implementazione dell'evento INotifyPropertyChanged in modo da poter rilevare le modifiche. Alcuni esempi di codice:

using System; 
using System.Dynamic; 
using System.ComponentModel; 

class Program { 
    static void Main(string[] args) { 
    dynamic obj = new ExpandoObject(); 
    obj.test = 42;  // Add a property 
    Console.WriteLine(obj.test); 

    var inpc = (INotifyPropertyChanged)obj; 
    inpc.PropertyChanged += inpc_PropertyChanged; 
    obj.test = "foo"; 
    Console.ReadLine(); 
    } 

    static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e) { 
    Console.WriteLine("'{0}' property changed", e.PropertyName); 
    } 

} 
+0

Grazie per la spiegazione e il codice Hans. Tuttavia, la mia richiesta è leggermente diversa. Voglio sapere che è possibile aggiungere la proprietà "test" al runtime? Voglio dire che non conosciamo nemmeno il nome della proprietà in fase di progettazione. Qualcosa come: obj.SetProperty (stringVariable) = anotherStringVariable. – virtualmic

+0

Erm, no.Perché non usi semplicemente un dizionario ? –

+0

Così posso facilmente collegarmi all'interfaccia utente di Windows Form – virtualmic

4

E 'possibile aggiungere proprietà delegare a ExpandoObject, che poi agire (quasi) come metodi. ad esempio,

dynamic obj = new ExpandoObject(); 
obj.GetDocumentTemplate =() => { ... }; 
... 
obj.GetDocumentTemplate(); // invokes delegate 
2

Ho appena scoperto questo fatto interessante: XAML I collegamenti a un ExpandoObject creeranno anche le proprietà che l'associazione sta tentando di accedere a.

ho ancora bisogno di più creatività per scoprire che cosa questo potrebbe essere un bene per. Creazione di oggetti dinamici nell'interfaccia utente? Suona bene: D Proverò qualcosa.

Problemi correlati