Necesito ver el evento endresize en WPF.¿Cómo atrapar la ventana de cambio de tamaño final?
Respuesta
WPF no proporciona un evento que solo se dispare al final del proceso de cambio de tamaño. SizeChanged es el único evento asociado con el cambio de tamaño de la ventana, y se disparará varias veces durante el proceso de cambio de tamaño.
Un truco total sería establecer constantemente un contador de tiempo cuando se activa el evento SizeChanged. Entonces, el temporizador no tendrá la posibilidad de marcar hasta que el cambio de tamaño termine y en ese punto realice su procesamiento de una sola vez.
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();
}
void _resizeTimer_Tick(object sender, EventArgs e)
{
_resizeTimer.IsEnabled = false;
//Do end of resize processing
}
Extensiones reactivas para .NET ofrece algunas capacidades realmente geniales para tratar con patrones de eventos estándar que incluyen la posibilidad de regular los eventos. Tuve un problema similar al lidiar con los cambios de tamaño de los eventos y, aunque la solución todavía es algo "hacky", creo que Reactive Extensions ofrece una forma mucho más elegante de implementarlo. Aquí está mi aplicación:
IObservable<SizeChangedEventArgs> ObservableSizeChanges = Observable
.FromEventPattern<SizeChangedEventArgs>(this, "SizeChanged")
.Select(x => x.EventArgs)
.Throttle(TimeSpan.FromMilliseconds(200));
IDisposable SizeChangedSubscription = ObservableSizeChanges
.ObserveOn(SynchronizationContext.Current)
.Subscribe(x => {
Size_Changed(x);
});
Esto le estrangular efectivamente el SizeChanged
caso de tal manera que su método de Size_Changed (donde se puede ejecutar código personalizado) no se ejecutará hasta 200 milisegundos (o el tiempo que le gustaría que esperar) han pasado sin otro evento SizeChanged
que se está disparando.
private void Size_Changed(SizeChangedEventArgs e) {
// custom code for dealing with end of size changed here
}
¡Realmente elegante! – MuiBienCarlota
Puede detectar exactamente cuándo cambiar el tamaño de una ventana de WPF terminó, y no es necesario un temporizador. Una ventana nativa recibe el mensaje WM_EXITSIZEMOVE
cuando el usuario suelta el botón izquierdo del mouse al final de una ventana cambiar el tamaño o mover operación. Una ventana de WPF no recibe este mensaje, por lo que debemos conectar una función WndProc
que la recibirá. Podemos usar HwndSource
con WindowInteropHelper
para obtener nuestro identificador de ventana. Luego agregaremos el gancho a nuestra función WndProc
. Haremos todo lo que en el caso Loaded
ventana (código de vb.net):
Dim WinSource As HwndSource
Private Sub WindowLoaded_(sender As Object, e As RoutedEventArgs)
WinSource = HwndSource.FromHwnd(New WindowInteropHelper(Me).Handle)
WinSource.AddHook(New HwndSourceHook(AddressOf WndProc))
End Sub
Ahora, en nuestro WndProc
, vamos a escuchar el mensaje WM_EXITSIZEMOVE
:
Const WM_EXITSIZEMOVE As Integer = &H232
Private Function WndProc(hwnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr, ByRef handled As Boolean) As IntPtr
If msg = WM_EXITSIZEMOVE Then
DoWhatYouNeed()
End If
Return IntPtr.Zero
End Function
Esto y una técnica similar se explica here y here.
Observe que la función debe devolver IntPtr.Zero. Además, no haga nada en esta función excepto manejar los mensajes específicos que le interesen.
Ahora, WM_EXITSIZEMOVE
también se envía al final de una operación de traslado, y solo estamos interesados en cambiar el tamaño. Hay varias formas de determinar que este fue el final de la operación de cambio de tamaño. Lo hice escuchando el mensaje WM_SIZING
(que se envió muchas veces durante el cambio de tamaño), combinado con un indicador. La solución entera se ve así:
(Nota: No se confunda con el código de destacar en este sentido, la causa de su mal vb.net)
Dim WinSource As HwndSource
Const WM_SIZING As Integer = &H214
Const WM_EXITSIZEMOVE As Integer = &H232
Dim WindowWasResized As Boolean = False
Private Sub WindowLoaded_(sender As Object, e As RoutedEventArgs)
WinSource = HwndSource.FromHwnd(New WindowInteropHelper(Me).Handle)
WinSource.AddHook(New HwndSourceHook(AddressOf WndProc))
End Sub
Private Function WndProc(hwnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr, ByRef handled As Boolean) As IntPtr
If msg = WM_SIZING Then
If WindowWasResized = False Then
'indicate the the user is resizing and not moving the window
WindowWasResized = True
End If
End If
If msg = WM_EXITSIZEMOVE Then
'check that this is the end of resize and not move operation
If WindowWasResized = True Then
DoWhatYouNeed()
'set it back to false for the next resize/move
WindowWasResized = False
End If
End If
Return IntPtr.Zero
End Function
Eso es todo.
¡Muchas gracias por esta pista! La solución con un temporizador es muy mala ... –
Deberíamos manejar 'WM_ENTERSIZEMOVE' en lugar de' WM_SIZING', creo. – yumetodo
- 1. Permitir el cambio de tamaño de la ventana pyGame
- 2. Ancho mínimo en el cambio de tamaño de la ventana
- 3. Cómo atrapar el evento de minimizar ventana?
- 4. cambio de tamaño de la cuadrícula al cambiar el tamaño de la ventana del navegador
- 5. Desactivar el cambio de tamaño de navegador Silverlight 4 Ventana
- 6. JScrollpane cambio de tamaño con contenido de tamaño variable
- 7. Cambio de tamaño dinámico de una ventana en Xaml
- 8. Gridpanel cambio de tamaño automático en el tamaño de la ventana
- 9. Ventana WPF: solo permite el cambio de tamaño horizontal
- 10. ¿Cómo desencadenar el evento de cambio de tamaño de la ventana en JavaScript?
- 11. ¿Cómo vincular el cambio de tamaño de escenario con el cambio de tamaño de los componentes?
- 12. ¿Cómo hacer que el mensaje de Tkinter se amplíe cuando cambio el tamaño de la ventana?
- 13. ¿cómo podemos deshabilitar el cambio de tamaño de la nueva ventana emergente en Firefox?
- 14. android: Cómo evitar el cambio de tamaño de la ventana cuando se muestra el teclado virtual
- 15. ¿Cómo agrego un evento de cambio de tamaño a la ventana en una vista usando Backbone?
- 16. Cómo llamar a una función en jQuery en el cambio de tamaño de la ventana?
- 17. cambio de tamaño activo de widgets dentro de la ventana principal
- 18. Cambio de tamaño de la ventana gráfica dentro de un iFrame
- 19. ¿Cómo puedo crear espaciadores de cambio de tamaño en JavaFX?
- 20. Tamaño de ventana de WPF
- 21. JQuery: altura dinámica() con el cambio de tamaño de la ventana()
- 22. ¿hay un evento vim activado por el cambio de tamaño de la ventana del terminal?
- 23. Cambiar el tamaño de la ventana usando QPropertyAnimation
- 24. tamaño de la ventana observable utilizando nocaut
- 25. Cambio de tamaño de UIViews
- 26. UIModalPresentationFormSheet cambio de tamaño vista
- 27. Desencadenar evento de cambio de tamaño en la impresión
- 28. GWT cambiar el tamaño y el centro de la ventana emergente cuando el tamaño de la ventana del navegador
- 29. Tamaño de la ventana emergente en android
- 30. Habilitar maximizar, minimizar y restaurar la ventana en WPF (cambio de tamaño manual es deshabilitar)
Form.ResizeBegin/End in Winforms. La notificación todavía está allí, pero se ignora en WPF. Dos pasos adelante, un paso atrás. –
@Martin, explica por qué pusiste _resizeTimer.IsEnabled = verdadero; antes de parar y comenzar? Eso no tiene sentido para mí. –
Me gusta este mecanismo porque permite hacer algunos procesamientos cuando el usuario pausa un cambio de tamaño. Tenía una situación en la que era necesario volver a diseñar el lienzo cuando el usuario cambiaba el tamaño. Con este enfoque de temporizador cuando el usuario dejó de mover el mouse (pero no lo liberó) se puede ejecutar el re-diseño y se puede ver el efecto del nuevo tamaño. A mi equipo de pruebas le gustó más que al anterior; el nuevo diseño solo se produjo cuando se lanzó el mouse, es decir, el enfoque WM_EXITSIZEMOVE. Establecí el intervalo del temporizador en 200 ms en lugar del valor 1500 utilizado en este código de ejemplo. – pjm