2012-07-13 8 views
6

In generale, ho inizializzato le proprietà dello Window prima dello InitializeComponent() e dell'impostazione dei controlli contenuti in seguito. Tuttavia, non sono stato del tutto coerente, e non ho notato un problema con l'ordinamento. Quindi:In un costruttore per una finestra WPF, cosa deve succedere prima di InitializeComponent() e dopo?

  • Sono (potenzialmente) facendo qualcosa di orribile? In particolare, ci sono problemi con l'impostazione delle proprietà dei controlli figlio prima dello InitializeComponent()?
  • Qual è il bello stile in questo senso?

Edit: Dato che le prime due risposte che ho ricevuto sono stati un po 'contraddittorio, mi permetta di essere più specifico:

public Foo Foo {get; protected set} 
public FooWindow (Foo foo) 
{ 
    Foo = foo; 
    this.Closing += FooWindow_Closing; 
    Foo.Frobbed += Foo_Frobbed; 

    InitializeComponent(); 

    this.DataContext = this; 
    this.Title = Foo.Name() + " Window"; 

    FooListView.ItemSource = Foo.CalculateList(); 

    FocusManager.SetFocusedElement(this, FooListView); 
} 

È questo circa la destra? Dovrei semplicemente fare MVVM e non avere nulla nel mio costruttore Window?

risposta

4

Chiamando InitializeComponents dopo qualche altro codice si corre il rischio di sovrascrivere accidentalmente le proprietà con elementi impostati in XAML o di utilizzare un oggetto non inizializzato. Di solito il code-behind è una priorità più alta rispetto a XAML, quindi lascerei InitializeComponents (ovvero, analizza e carica XAML) nella parte superiore.

+5

E 'importante notare che, se si utilizza MVVM, il DataContext deve essere impostata prima di ** ** di chiamare InitializeComponent(), oppure le associazioni ViewModel non sarà possibile ottenere impostato correttamente. InitializeComponent() chiama tutti i getter di associazione di proprietà, quindi se viene chiamato per primo, i bind non otterranno i valori corretti finché non verrà richiamato NotifyPropertyChanged su ciascuna proprietà. Questo stesso principio si applica a qualsiasi altra logica di inizializzazione che possa influire sul modo in cui xaml viene inizializzato. – jeff17237

2

Io di solito chiamo tutto ciò che non richiede l'albero visivo prima chiamo InitializeComponent().

Tutte le mie implementazioni utilizzano lo schema MVVM, quindi preferisco avere il mio ViewModel istanziato e popolato prima che l'interfaccia utente venga caricata sul client.

Se si carica sempre InitializeComponent() prima, si corre il rischio di creare un'esperienza utente cattivo, mostrando una visione disabitata che aggiorna improvvisamente contro uno che è popolata quando si entra in vista.

+0

È davvero un problema? Voglio dire, l'utente non può vedere il controllo fino a quando non chiamiamo 'Window.Show()', cosa che non succederà fino a quando il costruttore non esce completamente. Suppongo che potrebbe essere più un problema per un 'UserControl', ma anche in quel caso, l'oggetto dovrebbe essere completamente compilato al momento dell'assegnazione. – seeker

+0

Sì, può essere un problema. – Xcalibur37

3

In risposta alle vostre domande specifiche:

Am I (potenzialmente) di fare qualcosa di orribile? In particolare, ci sono problemi con l'impostazione delle proprietà dei controlli figlio prima di InitializeComponent()?

È probabile che i controlli figlio non siano ancora disponibili nel codice finché non si chiama InitializeComponents. In genere sarebbe una cattiva forma farlo.

Qual è lo stile buono in questo senso?

Questa sarà una questione di gusti, ma in generale mi sento di raccomandare che se hai intenzione di sfruttare la separazione che XAML ti offre, la prenderei il più lontano possibile. Se stai facendo cose logicamente sull'interfaccia utente, prova a farlo in XAML. Non è tanto una cosa MVVM quanto una separazione della presentazione dalla logica. La maggior parte di ciò che hai nel tuo codice di esempio può essere fatto in modo dichiarativo, anche se solo attraverso ValueConverters.

E.g se Foo era DependencyProperty, quindi è possibile allegarlo anche in XAML e aggiungere i callback come parte del callback ValueChanged. Di nuovo, questo non è MVVM, ma è piuttosto fondamentale per WPF.

Per la maggior parte delle altre cose, in realtà è probabile che si desideri attendere fino a quando viene chiamato OnLoaded, anziché eseguire il lavoro nel costruttore.

Speranza che aiuta,

+0

Sto iniziando a credere alla prima parte, ma non c'è un problema (come menzionato in [questa domanda] (http://stackoverflow.com/questions/1654490/wpf-bad-practice-to-put-code -directly-after-initializecomponent)) di OnLoaded che viene chiamato più volte? – seeker

+1

OnLoaded verrà chiamato ogni volta che viene caricato il controllo, che è il momento giusto per agganciare gli eventi e così via. Dovrai anche sganciarli in OnUnloaded. Se questa è una finestra, in realtà non dovresti mai vedere OnLoaded richiamato più volte, ma in genere devi fare attenzione con i controlli (la domanda collegata si riferisce a Pages, che verrebbe spesso caricata/scaricata). –

+0

Grazie per la tua risposta informativa. (Mi dispiace, posso accettare solo una risposta, e l'altra è venuta prima.) – seeker

Problemi correlati