Вы можете точно определить, когда изменение размера окна WPF закончилось, и вам не нужен таймер.Собственное окно получает сообщение WM_EXITSIZEMOVE
, когда пользователь отпускает левую кнопку мыши в конце окна, изменяя размер операции или .Окно WPF не получает это сообщение, поэтому нам нужно подключить функцию WndProc
, которая его получит.Мы можем использовать HwndSource
с WindowInteropHelper
, чтобы получить дескриптор нашего окна.Затем мы добавим хук к нашей функции WndProc
.Мы сделаем все это в событии окна Loaded
(код 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
Теперь в нашем WndProc
мы будем слушать сообщение 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
Этот и аналогичный метод объясняются здесь и здесь .
Обратите внимание, что функция должна возвращать IntPtr.Zero.Кроме того, не выполняйте в этой функции ничего, кроме обработки определенных сообщений, которые вас интересуют.
Теперь WM_EXITSIZEMOVE
также отправляется в конце операции перемещения, а нас интересует только изменение размера.Есть несколько способов определить, что это был конец операции изменения размера.Я сделал это, прослушав сообщение WM_SIZING
(которое отправлялось много раз при изменении размера) в сочетании с флагом.В целом решение выглядит так:
(Примечание: не путайте с выделенным здесь кодом, потому что это неправильно для 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
Вот и все.