如何捕捉结束调整大小窗口?
我需要捕获 WPF 中的 endresize 事件。
I need catch the event endresize in WPF.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我需要捕获 WPF 中的 endresize 事件。
I need catch the event endresize in WPF.
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
WPF 不提供仅在调整大小过程结束时触发的事件。 SizeChanged 是与窗口大小调整相关的唯一事件 - 在调整大小过程中它将多次触发。
一个彻底的技巧是在 SizeChanged 事件触发时不断设置一个计时器。然后计时器将没有机会计时,直到调整大小结束,然后进行一次性处理。
WPF doesn't provide an event that solely fires at the end of the resize process. SizeChanged is the only event associated with Window resizing - and it will fire multiple times during the resizing process.
A total hack would be to constantly set a timer ticking when the SizeChanged event fires. Then timer will not get a chance to tick until resizing ends and at that point do your one time processing.
.NET 的反应式扩展提供了一些非常酷的功能来处理标准事件模式,包括能够限制事件。我在处理大小更改事件时遇到了类似的问题,虽然解决方案仍然有点“hacky”,但我认为反应式扩展提供了一种更优雅的实现方式。这是我的实现:
这将有效地限制
SizeChanged
事件,这样您的 Size_Changed 方法(您可以在其中执行自定义代码)直到 200 毫秒(或您想要等待的时间)后才会执行在没有触发另一个SizeChanged
事件的情况下通过。Reactive Extensions for .NET provides some really cool capabilities for dealing with standard event patterns including being able to throttle events. I had a similar problem in dealing with size changed events and while the solution is still somewhat "hacky" I think that Reactive Extensions provides a much more elegant way of implementing it. Here is my implementation:
This will effectively throttle the
SizeChanged
event such that your Size_Changed method (where you can execute custom code) will not be executed until 200 milliseconds (or however long you would like to wait) have passed without anotherSizeChanged
event being fired.不需要计时器,@Bohoo 提供的非常干净的解决方案,我只是将他的代码从 vb.net 改编为 c#
NO Timer Needed with very clean solution that have given by @Bohoo up, i just adapted his code from vb.net to c#
您可以准确检测 WPF 窗口调整大小何时结束,并且不需要计时器。当用户在窗口调整大小或移动操作结束时释放鼠标左键时,本机窗口会收到
WM_EXITSIZEMOVE
消息。 WPF 窗口不会接收此消息,因此我们需要连接一个 WndProc 函数来接收它。我们可以使用HwndSource
和WindowInteropHelper
来获取窗口句柄。然后我们将钩子添加到我们的WndProc
函数中。我们将在窗口Loaded
事件(vb.net 代码)中完成所有这些操作:现在,在我们的
WndProc
中,我们将监听WM_EXITSIZEMOVE
消息:对此和类似的技术进行了解释此处 和 此处。
请注意,该函数应返回 IntPtr.Zero。另外,除了处理您感兴趣的特定消息之外,不要在此函数中执行任何操作。
现在,
WM_EXITSIZEMOVE
也会在移动操作结束时发送,并且我们只对调整大小感兴趣。有多种方法可以确定调整大小操作是否结束。我通过监听WM_SIZING
消息(在调整大小期间发送了多次)并结合一个标志来做到这一点。整个解决方案如下所示:(注意:不要与此处突出显示的代码混淆,因为它对于 vb.net 是错误的)
就是这样。
You can detect exactly when a WPF window resize ended, and you don't need a timer. A native window receive the
WM_EXITSIZEMOVE
message when the user release the left mouse button at the end of a window resize or move operation. A WPF window doesn't receive this message, so we need to hook up aWndProc
function which will receive it. We can useHwndSource
withWindowInteropHelper
to get our window handle. Then we will add the hook to ourWndProc
function. We will do all that in the windowLoaded
event (vb.net code):Now, in our
WndProc
, we will listen to theWM_EXITSIZEMOVE
message:This and a similar technique is explained here and here.
Notice that the function should return IntPtr.Zero. Also, don't do in this func anything except handling the specific messages you are interested in.
Now,
WM_EXITSIZEMOVE
is also sent at the end of a move operation, and we are interested only in resize. There are several ways to determine that this was the end of resize operation. I did it by listening to theWM_SIZING
message (which sent many times during resize), combined with a flag. The whole solution looks like this:(Note: Don't get confused with the code highlighting here, cause its wrong for vb.net)
That's it.
对于带有 Rx 的 UWP (System.Reactive)
For UWP with Rx (System.Reactive)