2009-11-16 32 views
19

Estoy intentando cargar una ventana de preferencias para mi aplicación y me gustaría que el botón Aplicar se deshabilite inicialmente, luego cuando se actualiza una preferencia, el botón Aplicar se habilita nuevamente. Tengo algunos datos de controles vinculados a un objeto de preferencias y lo que sucede es que después de que se carga la ventana, se desencadenan los eventos del cuadro combinado. ¿Hay algún evento que esté garantizado que pase muerto después de que todo esté estable?¿Cuál es el último evento que se dispara al cargar una nueva ventana de WPF/C#?

Aquí es lo que mi código es el siguiente (el botón de aplicar siempre está habilitada después de que las cargas de ventana):

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    _preferencesData = new PreferencesDataContext(); 
    LayoutRoot.DataContext = _preferencesData; 
    ButtonApply.IsEnabled = false; 
} 

private void ComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) 
{ 
    ButtonApply.IsEnabled = true; 
} 

¿Es también interesante observar que esto sólo sucede con los cuadros de texto y los cuadros combinados, no casillas de verificación o botones de radio .

+0

Gracias por todas las buenas sugerencias. Terminé agregando un campo llamado "IsDirty" a mi objeto de datos de preferencias y luego vinculé la propiedad IsEnabled del botón aplicar a ese campo. De esta forma eliminé todos los eventos como lo sugirieron Joseph y Ascalonx. –

Respuesta

50

mejor solución para la simple necesidad

contestación de José es la mejor solución, con mucho, para su necesidad simple: Sólo tiene que utilizar el enlace de datos y dejar que el modelo de datos manejarlo.

respuesta a la pregunta planteada como

Hay escenarios más complejos cuando usted realmente no necesita el control después de absolutamente todo ha terminado de cargar y todos los eventos han disparado. No hay un solo evento que ocurra "último muerto", pero es fácil rodar el suyo de manera efectiva usando la cola Dispatcher.

Esta es la forma de hacerlo:

Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() => 
{ 
    var x = ComputeSomething(1, 2, 3); 
    DoSomething(x, "Test"); 
})); 

Todo dentro de la {} se ejecutará cuando WPF termina todo con una prioridad más alta que ContextIdle, que incluye todos los controladores de eventos, eventos cargados, los eventos de entrada, lo que hace , etc.

secuencia de eventos cuando se crea una ventana y muestra

Conforme a lo solicitado, aquí está la secuencia de los eventos más importantes en WPF cuando se crea una ventana y s hown:

  1. Constructores y getters/setters se llaman como se crean los objetos, incluyendo PropertyChangedCallback, ValidationCallback, etc., en los objetos que están siendo actualizados y cualquier objeto que heredan de ellos

  2. Como cada elemento se agrega a un árbol visual o lógico que activa su evento Intialized, lo que hace que se encuentren Estilos y desencadenantes aplicados además de cualquier inicialización específica del elemento que pueda definir [nota: Evento inicializado no disparado para hojas en un árbol lógico si no hay PresentationSource (por ejemplo, ventana) en su raíz]

  3. La ventana y todas las representaciones visuales no plegada sobre ella se miden, lo que provoca un ApplyTemplate en cada control, lo que hace que la construcción del árbol objeto adicional incluyendo más constructores y getters/setters

  4. la ventana y todas las representaciones visuales no plegada sobre ella están dispuestos

  5. la ventana y sus descendientes (tanto lógicas y visuales) recibir un evento Loaded

  6. Cualquier enlaces de datos que fallaron cuando estaban primer conjunto se vuelve a intentar

  7. La ventana y sus descendientes se les da la oportunidad de hacer que su contenido visualmente

los pasos 1-2 se realizan cuando se crea la ventana, si es o no se muestra. Los otros pasos generalmente no ocurren hasta que se muestra una ventana, pero pueden ocurrir antes si se activan manualmente.

+0

Ha escrito incorrectamente Invoke y falta una paren derecha antes del punto y coma, pero de lo contrario, ¡gracias! –

+0

Consideraría la prioridad 'cargada' en lugar de 'ContextIdle'. En ese caso, el método se procesa cuando el diseño y el procesamiento han finalizado, pero justo antes de que se atiendan los elementos con prioridad de entrada. –

+0

Increíble. ¡¡Muchas gracias!! – Asheh

11

que acabo de hacer clase de lo mismo behaviorly en una aplicación WPF bandeja del sistema.

Sin embargo, no lo hice mediante el manejo de eventos. Simplemente até la propiedad Habilitada de mi botón a una propiedad en mi ViewModel, y la propiedad se actualizó cada vez que necesité el comportamiento.

1

Al configurar el DataContext probablemente se activará el evento SelectionChanged, y no se puede confiar en cuándo exactamente se disparó. Una lógica de comprobar que está seleccionado exactamente sería más fiable:

private void ComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) 
{ 
    if (myComboBox.SelectedItem == null) 
    { 
     buttonApply.IsEnabled = false; 
    } 
    else 
    { 
     buttonApply.IsEnabled = true; 
    } 
} 

La razón por la que está pasando después con el código tal cual es debido a que el evento se pone en cola en el hilo de la interfaz de usuario, por lo que toca a Windows si ejecutará la siguiente línea de código en Load, o para manejar los otros eventos en la cola.

-3

Order of Events in Windows Forms

Control.HandleCreated

Control.BindingContextChanged

Form.Load

Control.VisibleChanged

Form.Activated

Form.Shown

+11

No relevante para la pregunta, ya que él pregunta por WPF y usted está hablando de WinForms. –

+0

WPF no winforms. – Asheh

1

no tirar un montón de cosas en que usted puede o no estar familiarizados con, pero si esto es un fenómeno relativamente nuevo código base, es posible que desee considerar el uso del patrón MVVM y use Commands en lugar del arcaico (énfasis mío) modelo de evento.

11

El evento Window.ContentRendered cumplió con mis requisitos.

Cuestiones relacionadas