2012-07-13 11 views
6

En general, he estado inicializando las propiedades del Window antes del InitializeComponent() y configurando los controles que se encuentran en él. Sin embargo, no he sido tan consistente, y realmente no he notado un problema con el orden. Entonces:En un constructor para una ventana de WPF, ¿qué debería pasar antes de InitializeComponent() y qué después?

  • ¿Estoy (potencialmente) haciendo algo horrible? En particular, ¿hay algún problema con la configuración de las propiedades de los controles secundarios antes del InitializeComponent()?
  • ¿Qué es un buen estilo en este sentido?

Editar: Dado que las dos primeras respuestas que recibí fueron un poco contradictorio, quiero ser más específico:

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); 
} 

es eso de verdad? ¿Debería hacer MVVM y no tener nada en mi constructor Window?

Respuesta

4

Al llamar a InitializeComponents después de algún otro código, se corre el riesgo de sobrescribir accidentalmente las propiedades con cosas que se establecieron en el XAML o de utilizar un objeto no inicializado. Por lo general, el código subyacente es una prioridad más alta que el XAML, así que dejaría InitializeComponents (también conocido como, analizar y cargar el XAML) en la parte superior.

+5

Es importante señalar que, si se utiliza MVVM, el DataContext se debe establecer antes ** ** llamar a InitializeComponent() o bien sus fijaciones ViewModel no conseguirá establecer correctamente. InitializeComponent() llama a todos los getters de enlace de propiedad, por lo que si se llama primero, sus enlaces no obtendrán los valores adecuados hasta que se llame nuevamente a NotifyPropertyChanged en cada una de sus propiedades. Este mismo principio se aplica a cualquier otra lógica de inicialización que pueda afectar cómo se inicializa su xaml. – jeff17237

2

Normalmente llamo a cualquier cosa que no requiera el árbol visual antes de llamar al InitializeComponent().

Todas mis implementaciones usan el patrón MVVM, por lo que prefiero que mi ViewModel se instale y llene antes de que la UI se cargue en el cliente.

Si siempre carga InitializeComponent() primero, corre el riesgo de crear una mala experiencia de usuario al mostrar una vista despoblada que se actualiza repentinamente frente a una que se llena cuando se ve.

+0

¿Esto realmente es un problema? Quiero decir, el usuario no puede ver el control hasta que llamemos a 'Window.Show()', lo que no ocurrirá hasta que el constructor salga por completo. Supongo que podría ser más un problema para un 'UserControl', pero incluso así, el objeto debería estar completamente construido para el momento en que se lo asignó. – seeker

+0

Sí, puede ser un problema. – Xcalibur37

3

En respuesta a sus preguntas específicas:

Am I (potencialmente) haciendo algo horrible? En particular, ¿hay algún problema con la configuración de las propiedades de los controles secundarios antes de InitializeComponent()?

Lo más probable es que los controles secundarios todavía no estén disponibles para usted en el código hasta que haya llamado a InitializeComponents. En general, sería mala forma hacer esto.

¿Qué es un buen estilo en este sentido?

Esto va a ser una cuestión de gusto, pero en general, recomendaría que si va a aprovechar la separación que XAML le brinda, entonces lo llevaría todo lo lejos que pueda. Si estás haciendo cosas lógicamente relacionadas con la interfaz de usuario, intenta hacerlo en XAML. Esto no es tanto una cosa MVVM, ya que es una separación de la presentación de la lógica. La mayor parte de lo que tienes en tu código de muestra se puede hacer de manera declarativa, incluso si solo a través de ValueConverters.

E.g si Foo era una DependencyProperty, entonces también podría adjuntarlo en XAML y agregar las devoluciones de llamadas como parte de la devolución de llamada ValueChanged. De nuevo, esto no es MVVM, pero es bastante fundamental para WPF.

Para la mayoría de las otras cosas, probablemente desee esperar hasta que se llame a OnLoaded, en lugar de hacer el trabajo en el constructor.

Espero que ayude,

+0

Estoy empezando a creer en la primera parte, pero ¿hay algún problema? (Como se menciona en [esta pregunta] (http://stackoverflow.com/questions/1654490/wpf-bad-practice-to-put-code -directly-after-initializecomponent)) de OnLoaded siendo llamado varias veces? – seeker

+1

Se enviará una llamada a OnLoaded cada vez que se cargue el control, que es un momento apropiado para enlazar eventos y demás. También querrás desengancharlos en OnUnloaded. Si se trata de una ventana, entonces nunca debería ver OnLoaded llamado varias veces, pero es algo de lo que generalmente se debe tener cuidado con los controles (la pregunta vinculada hace referencia a las páginas, que con frecuencia se cargarían/​​descargarían). –

+0

Gracias por su respuesta informativa. (Lo siento, solo puedo aceptar una respuesta, y la otra fue primero). – seeker

Cuestiones relacionadas