WPF에서 이벤트 endresize를 잡아야합니다.결말 크기 조정 창을 잡는 방법?
답변
WPF는 크기 조정 프로세스가 끝날 때 발생하는 이벤트를 제공하지 않습니다. SizeChanged은 창 크기 조정과 관련된 유일한 이벤트이며 크기 조정 과정에서 여러 번 실행됩니다.
전체 해킹은 SizeChanged 이벤트가 발생하면 타이머가 똑딱 거리는 것을 계속 설정하는 것입니다. 그런 다음 타이머는 크기 조정이 끝날 때까지 틱 할 기회를 얻지 않으며 그 시점에서 한 번 처리합니다.
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
}
.NET 용 Reactive Extensions에는 이벤트를 조절할 수있는 기능을 포함하여 표준 이벤트 패턴을 처리 할 수있는 몇 가지 유용한 기능이 있습니다. 크기가 변경된 이벤트를 처리 할 때도 비슷한 문제가 있었지만 솔루션이 여전히 "해킹"되는 반면 Reactive Extensions는 훨씬 더 우아한 구현 방법을 제공한다고 생각합니다.
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);
});
이 효과적으로 (사용자 정의 코드를 실행할 수 있습니다) 당신의 SIZE_CHANGED 방법은 200 밀리 초까지 실행되지 않습니다 (또는 그러나 당신이 기다릴하고자)하는 SizeChanged
이벤트 등을 스로틀 것이다있다 : 여기 내 구현 SizeChanged
이벤트가 발생하지 않고 전달되었습니다.
private void Size_Changed(SizeChangedEventArgs e) {
// custom code for dealing with end of size changed here
}
정말 우아합니다! – MuiBienCarlota
정확히 언제 WPF 창의 크기가 조정되었는지를 감지 할 수 있으며 타이머가 필요하지 않습니다. 네이티브 윈도우는 사용자가 윈도우 크기 변경 또는 이동 작업의 끝에서 마우스 왼쪽 버튼을 놓을 때 WM_EXITSIZEMOVE
메시지를 수신합니다. WPF 창이이 메시지를받지 못하기 때문에 수신 할 WndProc
함수를 연결해야합니다. 우리는 창 핸들을 얻기 위해 HwndSource
을 WindowInteropHelper
과 함께 사용할 수 있습니다. 그런 다음 우리의 WndProc
함수에 후크를 추가 할 것입니다. 우리는 창 Loaded
경우에 모든 것을 할 것입니다 (vb.net 코드) : 우리의 WndProc
에서 지금
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
, 우리는 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
이와 유사한 기술을 here 및 here으로 설명됩니다.
이 함수는 IntPtr.Zero를 반환해야합니다. 또한이 func에서는 관심있는 특정 메시지를 처리하는 것을 제외하고는하지 마십시오.
이제는 이동 작업이 끝날 때 WM_EXITSIZEMOVE
이 전송되며 크기 조정에만 관심이 있습니다. 이 작업이 크기 조정 작업의 끝임을 확인하는 데는 여러 가지 방법이 있습니다. 나는 깃발과 결합 된 WM_SIZING
메시지 (크기 재조정 중에 여러 번 보낸 메시지)를 들음으로써 그것을했다. 전체 솔루션은 다음과 같습니다
: 그것 뿐이다
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
을 (참고, 여기에 강조 코드와 혼동 vb.net에 대한 잘못이 발생하지 마십시오).
이 힌트를 주셔서 대단히 감사합니다! 타이머가있는 솔루션은 매우 좋지 않습니다. –
우리는'WM_SIZING' 대신'WM_ENTERSIZEMOVE'를 처리해야한다고 생각합니다. – yumetodo
- 1. Java에서 이미지 크기 조정. 크기 조정 방법
- 2. 자동 크기 조정 방법
- 3. NSWindow 크기 조정 제한
- 4. vb.net에서 이미지 조작/크기 조정/크기 조정
- 5. 크기 조정 div 윈도우에서의 너비 크기 조정
- 6. 여러 비트 맵의 크기 조정/크기 조정
- 7. WPF Windows 크기 조정
- 8. GWT 크기 조정 DialogBox
- 9. 크기 조정 플래시 단계
- 10. 크기 조정 컨트롤이있는 팝업
- 11. 플렉스의 이벤트 크기 조정
- 12. UIScrollView없이 이미지 크기 조정
- 13. Perl TK 크기 조정 창
- 14. 자바 스크립트 브라우저 크기 조정
- 15. 이미지 크기 축소 크기 조정
- 16. WPF 글꼴 크기 조정
- 17. 공간에서 jquery 결말 문자열
- 18. IE에서 이미지 크기 조정
- 19. Qt : 경계선없는 위젯 크기 조정
- 20. 결말 요소의 공간을 제거 하시겠습니까?
- 21. Silverlight 3 : 크기 조정 모델/100 % 크기
- 22. 인쇄 화면의 작동 방식/투명 창을 잡는 방법!
- 23. 터치 제스처로 UIView 이동, 크기 조정 및 크기 조정
- 24. RMagick : 축소판 이미지 크기 조정 및 크기 조정
- 25. NSWindow에 대한 크기 조정 코너/핸들 크기 조정 방법은 무엇입니까?
- 26. PHP 이미지 크기 조정 및 크기 조정 이미지 저장
- 27. jQuery 크기 조정 문제 정렬 가능 크기 조정 가능 draggable
- 28. 플렉스 구성 요소 크기 조정 및 크기 조정
- 29. iPad - 라벨 이동 및 크기 조정 방법
- 30. Grails는 : 나는 크기 조정 방법 ImageController이 응답
Form.ResizeBegin/End in Winforms. 알림은 여전히 있지만 WPF에서는 무시됩니다. 두 걸음 앞으로, 한 걸음 뒤로. –
@ 마틴, 이유를 설명 해주세요 _resizeTimer.IsEnabled = true; 그만 시작하기 전에? 저에게는 감각이 없어 보입니다. –
사용자가 크기를 일시 정지 할 때 일부 처리를 수행 할 수 있으므로이 메커니즘이 마음에 듭니다. 사용자가 크기를 조정할 때 캔버스를 다시 배치해야하는 상황이있었습니다. 이 타이머 방식을 사용하면 사용자가 마우스를 움직일 때 멈추었지만 마우스를 놓지 않아도 다시 레이아웃을 실행하고 새 크기의 영향을 볼 수 있습니다. 내 테스트 팀이 이전보다 마우스 포인터를 놓았을 때만 마우스를 튕겨서 다시 훑어 보았습니다. 즉 WM_EXITSIZEMOVE 접근 방식입니다. 이 예제 코드에서 사용 된 1500 값 대신 타이머 간격을 200ms로 설정했습니다. – pjm