2009-02-04 25 views
5

Tengo un mapa de formularios de Windows en WindowsFormsHost, y necesito que cambie el tamaño de la ventana.¿Cómo puedo saber cuándo WindowsFormsHost está redimensionando en WPF?

No estoy seguro de qué evento escuchar, para hacer esto. Necesito que el mapa cambie de tamaño solo una vez que el mouse esté activo, de lo contrario, se queda atrás y trata de dibujarse un millón de veces cuando cambias el tamaño de una ventana muy despacio.

Respuesta

7

Esperar con un temporizador es una idea muy, muy mala, simplemente, es una heurística y está adivinando cuando se realiza la operación de cambio de tamaño.

Una mejor idea sería derivar una clase de WindowsFormsHost y anular el método WndProc, manejando el mensaje WM_SIZE. Este es el mensaje que se envía a una ventana cuando se completa la operación de tamaño (a diferencia de WM_SIZING, que se envía durante el proceso).

También puede manejar el mensaje WM_SIZING, y no llamar a la implementación base de WndProc cuando recibe este mensaje, para evitar que el mensaje se procese y hacer que el mapa se rediseñe todas esas veces.

La documentación para el método de la clase WndProcControl muestra cómo reemplazar WndProc método:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc(VS.71).aspx

A pesar de que es de una clase diferente, es el mismo principio exacto.

Además, se necesitan los valores para los WM_SIZING y WM_SIZE constantes, que se pueden encontrar aquí:

http://www.pinvoke.net/default.aspx/Enums/WindowsMessages.html

Tenga en cuenta que no es necesario todo, desde el enlace de arriba, a las declaraciones de esos dos valores:

/// <summary> 
/// The WM_SIZING message is sent to a window that 
/// the user is resizing. By processing this message, 
/// an application can monitor the size and position 
/// of the drag rectangle and, if needed, change its 
/// size or position. 
/// </summary> 
const int WM_SIZING = 0x0214; 

/// <summary> 
/// The WM_SIZE message is sent to a window after its 
/// size has changed. 
/// </summary> 
const int WM_SIZE = 0x0005; 
+0

He borrado mi respuesta, no estaba tratando de asumir que debe ejecutar el temporizador todo el tiempo. De cualquier manera, estoy interesado en este método. Cualquier enlace o muestras? – bendewey

+0

pinvoke.net es tu amigo ... =) –

-3

por la sugerencia aquí:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8453ab09-ce0e-4e14-b30b-3244b51c13c4

Sugieren utilizar el temporizador y cada vez que se dispara el evento SizeChanged, simplemente reinicia el temporizador. De esta forma, el temporizador no llama "Marcar" todo el tiempo para verificar si el tamaño ha cambiado: el temporizador solo se apaga una vez por cada cambio de tamaño. Tal vez menos que ideal, pero no tengo que lidiar con nada de Windows de bajo nivel. Este enfoque funciona para cualquier control de usuario de wpf, no solo para wpf windows.

public MyUserControl() 
{ 
    _resizeTimer.Tick += _resizeTimer_Tick; 
} 

DispatcherTimer _resizeTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 1500), IsEnabled = false }; 

private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    _resizeTimer.IsEnabled = true; 
    _resizeTimer.Stop(); 
    _resizeTimer.Start(); 
} 

int tickCount = 0; 
void _resizeTimer_Tick(object sender, EventArgs e) 
{ 
    _resizeTimer.IsEnabled = false; 
    //you can get rid of this, it just helps you see that this event isn't getting fired all the time 
    Console.WriteLine("TICK" + tickCount++); 

    //Do important one-time resizing work here 
    //... 
} 
Cuestiones relacionadas