2010-09-14 16 views
5

Sto per creare un'applicazione WPF. Fino ad ora l'unico modo in cui abbiamo fatto GUI è avere una finestra principale con un file code-behind per gestire i clic dei pulsanti ecc.Windows form/WPF troppo grandi, come posso dividerlo?

Il mio problema è che con l'aumentare dell'applicazione, la GUI cresce e la dimensione del codice dietro il file può diventare davvero fuori controllo!

Ho identificato circa 15 casi d'uso principali per il mio sistema (esempio: inserire dettagli, visualizzare dettagli, ecc ...). Sto creando una finestra principale (dimensione: 480x320) che consiste di 15 schermi separati (uno per ogni caso d'uso). Questo potrebbe essere ottenuto con un TabControl centrato e allungato, con 15 TabItem. O più probabilmente potrebbe essere solo un mucchio di contenitori sovrapposti, uno sopra l'altro (solo uno visibile alla volta).

Il punto è, con 15 schermate separate, il mio file code-behind diventerà enorme (per non parlare del file xaml!): Giocoleria tra gli stati - facendo 14 collassati/nascosti e rendendoli visibili, Gestendo i controlli per 15 schermi diversi.

C'è un modo per avere 15 moduli separati, ognuno con il proprio file code-behind, invece di 15 TabItems su un modulo, e quindi avere un motore principale che li crea e li elimina se necessario? Ovviamente, dovrebbe apparire come se fosse una forma, non 15 pop-up.

Come gestirlo? Come gestiresti il ​​problema dei file xaml e code-behind che sono migliaia di righe?

risposta

5

I suoi istinti sono buoni: si non si vuole mettere tutto in un'unica finestra. Sarebbe molto meglio mettere ognuno dei 15 "schermi" nel proprio file XAML, come controlli utente o pagine.

Se la navigazione in stile browser Web avrebbe senso per l'applicazione, quindi osservare la classe Page. Se si imposta l'applicazione StartupUri per puntare a una pagina (anziché una finestra), verrà visualizzata automaticamente una finestra con i pulsanti Indietro e Avanti, e sarà possibile utilizzare Hyperlink s (impostare la proprietà NavigateUri in modo che punti a un'altra pagina) o i metodi di NavigationService per navigare verso le nuove pagine.

Se non si desidera utilizzare i pulsanti Indietro e Avanti, inserire ciascuno "schermo" nel proprio UserControl e aggiungere una minima logica alla finestra principale per visualizzarli e nasconderli. Oppure, se stai utilizzando MVVM, potresti impostare un po 'di magia in cui cambi solo la DataContext (o meglio ancora una proprietà del ViewModel a livello di applicazione) della finestra e carica e mostra automaticamente l'UserControl corretto (guarda in DataTemplate s, o guarda il video qui sotto).

Vorrei anche raccomandare vivamente di utilizzare MVVM per cercare di scrivere il minor numero possibile di codice (idealmente nessuno - non sempre ottenibile, ma imparerai molto provando). Questo rende XAML tonnellate più facile da refactoring. Se in seguito decidi che una delle tue griglie contiene troppe cose su di essa, puoi semplicemente tagliarla e incollarla in un nuovo UserControl, senza dover perdere un sacco di tempo per districare tutto il codebehind.

Poiché sembra che tu non abbia familiarità con il pattern MVVM, questo video potrebbe andare oltre la tua testa, ma non posso fare a meno di raccomandare il talk MIX2010 "Build Your Own MVVM Framework". Apre gli occhi su ciò che MVVM può fare e ha alcune idee solide su come gestire la navigazione tra diversi UserControls. (Ha anche un collegamento a un talk intro-MVVM.)

1

È necessario creare ciascuna schermata come UserControl e fare riferimento a quella nel MainWindow xaml.

Tuttavia, sembra che tu abbia un enorme difetto di progettazione nella tua applicazione, cioè avere la tua logica nell'interfaccia utente. Il file code-behind non è lì per guidare la tua applicazione o la logica, è lì per guidare la tua interfaccia utente! Potresti voler dare uno sguardo al pattern MVC e alle dipendenze per risolvere questo problema.

Il Wpf Application Framework sarebbe un inizio per quello.

+0

+1 per suggerire una migliore metodologia –

+0

un gestore sarà responsabile di tutta la logica, o sarà in un riferimento dll .. ho pensato che sarebbe essere gentile/coerente anche per dividere la gui con i casi d'uso che ho trovato in analisi. – Mikey

+0

p.s. guarda male UserControl e ti faccio sapere, grazie !! – Mikey

-1

In termini di file code-behind, è possibile utilizzare i tag #Region per consentire di comprimere ed espandere le diverse schermate ... Anche se, dividendo fuori logicamente è un approccio migliore, se possibile

+1

L'ho già incontrato e mi colpisce sempre come una spazzatura sotto il tappeto. –

+0

Non sono d'accordo, ti aiuta a ordinare logicamente il tuo codice - raggruppa i gestori di eventi, le tue proprietà ecc. Le regioni –

+0

sono utili quando la classe diventa sufficientemente grande, ma se è sufficientemente grande da rendere indispensabili le regioni, allora probabilmente la classe è bisognoso di refactoring. Il caso che ho riscontrato è dove si apre un file e sembra che si adatta su due schermi. Quindi espandi alcune regioni; okay, ora è forse una dozzina. Oh, ma aspetta, c'erano regioni all'interno di quelle regioni; in effetti, quei due schermi avevano migliaia di righe. Tutto questo codice in una classe ha creato numerose opportunità di accoppiamento stretto ed ora è difficile testare un singolo pezzo in isolamento. –

-2

Si potrebbe crea la tua classe partial e suddividila in file separati.

+0

'partial' non è realmente [applicabile] (http://stackoverflow.com/q/17250559/1997232) in caso di xaml ed è un cattivo suggerimento in caso di winforms, in quanto dovresti occuparti di tutti i membri (es. nomi di campi) per non interferire tra loro (mancanza di incapsulamento). – Sinatr

6

Se stai per iniziare a utilizzare WPF dovresti dare un'occhiata al modello di progettazione MVVM e a commanding. Dovresti anche considerare l'utilizzo di dependency injection, tramite un container IOC, è piuttosto facile da configurare, questo è un ottimo tutorial.

Nel tuo esempio, sarebbe possibile creare una singola vista (controllo utente) che appare in una scheda rilevante, quella vista avrebbe la sua classe di modello di vista correlata che fornisce i dati e gestisce qualsiasi interazione tramite comandi. Ogni modello di vista sarebbe associato alla sua vista tramite il contenitore IOC, rendendo così più semplice modificare il comportamento dell'interfaccia utente.

Problemi correlati