2010-08-03 13 views
8

Ho una classe base (che rappresenta un contenitore del mondo reale pieno di piccole sfere) e alcune classi derivate. Questo funziona bene.
Il mio problema è come fare la loro visualizzazione. Ho un UserControl che visualizza la classe base. La soluzione migliore è avere un UserControl derivato per ciascuna delle classi derivate? O è meglio avere solo uno che lavori per tutti loro?
Modifica:
Apparentemente non ero abbastanza specifico. C'è sempre la stessa apparenza di base: rettangolo con molti cerchi all'interno. La differenza tra le classi è come il contenitore è riempito. Un tipo mette un seme nel mezzo e crea altre sfere in una struttura ad albero - in questo caso le linee di collegamento tra genitori e figli devono essere disegnate.
Generalmente, l'aspetto delle visualizzazioni delle classi dovrebbe essere coerente con alcune specialità per ciascun tipo derivato.Visualizzazione delle classi derivate in C#

+5

Stai cercando di vincere un concorso di conteggio jelly-bean? –

+1

Penso che questa sia una questione molto importante nell'ingegneria del software; Mi sono imbattuto in situazioni simili e non so davvero come risolverlo correttamente. È un peccato che tutte le risposte finora abbiano mancato il punto. – Timwi

+2

@James Curran: Sort of. Solo che non ci sono concorrenti e le jelly-bean sono sostituite con microsfere di vetro cavo – Lukas

risposta

0

Ho il sospetto che solo tu possa rispondere a questa domanda in modo definitivo. Un'interfaccia utente per una determinata sottoclasse è probabilmente ciò che si desidera, ma se le sottoclassi differiscono solo leggermente, è possibile trovare più semplice aggiungere una logica condizionale in un numero inferiore di controlli utente. Non penso ci sia una risposta esatta a questo.

0

Difficile dire solo dalla vaga descrizione. Avremmo davvero bisogno di sapere, almeno, quali sono le differenze tra le classi derivate.

In generale, con una conoscenza limitata, mi piacerebbe andare con un UserControl derivato per ogni classe derivata

0

se le classi di visualizzazione derivata non differiscono tra loro, poi, con tutti i mezzi, utilizzare uno UserControl. Il punto principale qui è ASCIUTTO.

1

Questo dipende molto dall'aspetto dei display. Se le visualizzazioni delle classi derivate sono molto simili alla classe base, è sufficiente che l'unico UserControl esegua la visualizzazione. OTOH, se ogni classe derivata ha bisogno di visualizzare cose uniche, allora sarà meglio avere un UserControl separato per visualizzare ogni classe derivata. Non posso davvero essere più specifico senza informazioni più specifiche sulle tue lezioni.

MODIFICA: Dalle tue informazioni aggiuntive direi che dovresti avere una classe di visualizzazione di base che disegna il contenitore rettangolare del commom e che ha ottenuto UserControls che gestiscono il disegno del contenuto di ciascun tipo specifico.

+0

Sono d'accordo con la risposta modificata. Chiedi alla tua classe base di fare tutto il disegno e ricava una classe e sovrascrivi quelli che cambiano tra i tipi. Si potrebbe avere un ciclo generico nella classe base che chiama un metodo 'draw next' che si sovrascrive nelle sottoclassi. –

0

Un approccio al problema sarebbe decomposizione seguendo la prospettiva MVVC:

Avrete bisogno di un UserControl come View.

Un pittore di base, che gestisce il dipinto della "scatola con cerchi in esso" come ViewModel. I pittori derivati ​​implementano diverse logiche di posizionamento degli oggetti e delle loro interconnessioni.

Se l'aspetto dei tuoi oggetti può variare, è necessario che vengano consegnati al pittore come ViewModel possibilmente attraverso il modello dell'adattatore.

Infine, le tue cerchie, i rettangoli e gli elementi associati ad essi sono il Modello.

generale:

View (UserControl) -> ViewModel (pittore + Imbianchini derivati ​​+ opporsi ViewModels) -> Modello (cerchio, rettangolo, ecc)

0

Non capisco appieno il vostro dominio del problema ma penso che tu debba rompere questo ancora un po '. decomponi il tuo modello in parti e scrivi viste per ogni parte, quindi puoi semplicemente collegarle di nuovo.

Scriverei una vista per le sfere, una vista per le linee tra le sfere e una vista per il rettangolo che contiene tutto, quindi ognuno dei modelli sarà responsabile dell'organizzazione e della creazione dei corrispondenti SphereModels e LineModels (e qualsiasi altra cosa hai bisogno) quindi la tua vista principale deve solo essere responsabile della posa di questi nella scatola.

Ricorda sempre preferire la composizione all'eredità! Concentrati su come suddividere il tuo problema in parti più piccole.

buona fortuna

0

penso che vorrei andare con una classe base Visualizer che ha avuto alcuni metodi protetti per disegnare i cerchi e linee, e forse qualche proprietà per la superficie di disegno (Canvas?) In modo ogni implementazione in grado di calcolare la misura posizioni basate su base, ecc.

La classe di base implementa tutti i metodi di interfaccia/puntelli necessari per renderlo un visualizzatore.

Utilizzare lo schema di strategia nel metodo chiamato IDE quando si suppone che il visualizzatore si disegna da sé ... l'implementazione del metodo potrebbe cancellare la tela, impostare i pennelli e altre cose che devono essere comuni a ogni implementazione, quindi chiama un metodo astratto della classe base che posiziona effettivamente i cerchi/scatole/linee/etc sulla tela.

In questo modo, ogni implementazione specifica deve solo preoccuparsi della logica per posizionare correttamente le cose in base al proprio insieme di regole - tutte le "cose ​​da disegno sulla tela" vengono mantenute nella classe base.

HTH

EDIT: Corretto errore di battitura che possono aver causato confusione, dove ho usato il termine "controllo" quando dire "visualizzatore".

0

Sembra una situazione con più soluzioni.

Un modo per farlo sarebbe impostare UserControl per chiamare un metodo virtuale nella classe base e quindi sovrascriverlo nelle classi derivate. Nelle classi derivate, puoi semplicemente chiamare l'implementazione di base per impostare inizialmente il frame.

È anche possibile impostarlo per il rendering in livelli (un livello contenitore, livello sfera, livello riga, ecc.) E fare in modo che la classe figlio esegua il rendering di tutti i livelli univoci e determini l'ordine. Questo può essere costoso, ma potrebbe smussare le immagini se la maggior parte dell'immagine rimane uguale.

Un altro è utilizzare i delegati piuttosto che l'ereditarietà, ma questo tende a diventare disordinato. Questa non è generalmente una buona idea a causa delle penalità prestazionali. Tuttavia, ha il vantaggio della flessibilità di runtime. A seconda del resto del codice, con questo modello potresti essere in grado di cambiare gli stili di crescita a metà. Se non ti vedi approfittare di questa flessibilità, ti consiglio comunque di utilizzare un modello diverso.

Indipendentemente dal metodo utilizzato, è consigliabile che la classe di base fornisca le routine di disegno comuni per garantire la coerenza.Le routine nella classe base dovrebbero essere utilizzate dalla maggior parte delle classi figlio, ma non necessariamente tutte. Questo di solito porta a un codice più gestibile (a meno che non si finisca con un file di linea da 10000), meno bug e meno sforzo.

Problemi correlati