2012-02-23 11 views
6

Nel mio progetto ho un modello e voglio associare lo stato visibile di un'etichetta utilizzando una delle proprietà del modello. Non voglio aggiungere un'altra proprietà ShowLabel al modello. Voglio essere in grado di scrivere qualcosa del genere:.net Associazione dati WinForms utilizzando Lambda anziché proprietà

label.Bindings.Add("Visible", model, m => m.Name != "Default"); 

Fondamentalmente voglio essere in grado di scrivere un'espressione lambda invece di aggiungere una proprietà da mio modello. È possibile?

risposta

2

L'associazione dati Windows Form riconosce l'interfaccia ICustomTypeDescriptor, che consente a un oggetto di decidere in fase di esecuzione quali proprietà presenta all'associazione dati. Quindi, se ne scrivi un'implementazione, puoi dire a Windows Form che hai le proprietà che desideri avere e puoi decidere come implementarle.

Naturalmente, ciò potrebbe non essere d'aiuto: se si desidera evitare l'aggiunta di una proprietà, è possibile evitare di implementare un'interfaccia abbastanza complessa. La soluzione ovvia sarebbe scrivere un tipo il cui compito è quello di fungere da origine dati e collegarlo a quello invece di qualsiasi oggetto al quale si sta legando attualmente.

Ovviamente, se si fa che è probabilmente più semplice implementare qualsiasi proprietà che si sarebbe implementata su quel wrapper.

In generale con l'associazione dati, si desidera evitare l'associazione diretta a un modello sottostante, proprio perché non si desidera aggiungere elementi al modello esclusivamente a vantaggio dell'interfaccia utente. Questo è il motivo per cui la 'presentazione separata' è molto popolare: invece di collegare direttamente il modello e la vista, si configura qualcosa nel mezzo il cui compito è quello di mediare. Alcuni chiamano questo un viewmodel, alcuni lo chiamano un presentatore, ma il principio di base è sempre la separazione della presentazione.

Sembra che tu stia cercando di ottenere una presentazione separata (che è buona) ma senza introdurre un tipo in più in modo che questo livello intermedio abbia un posto dove andare. Perché non basta definire una classe (o un insieme di classi) per agire come quel livello?

4

Sì, è possibile farlo utilizzando l'evento Format della classe Binding. Continuerai a legare alla proprietà in questione, ma il gestore di eventi Format restituirà un valore diverso (un bool in questo caso).

var binding = new Binding("Visible", model, "Name"); 
binding.Format += (sender, args) => args.Value = (string)args.Value != "Default"; 
label.DataBindings.Add(binding); 
+0

Funziona perfettamente. Stavo pensando di scrivere una piccola libreria per farlo, ma lanciare questo codice in un metodo è tutto ciò di cui ho bisogno. Grazie! –

Problemi correlati