我在 WindowsFormsHost 中有一个 Windows 窗体映射,我需要它来调整窗口大小。
我只是不确定要听什么事件来做到这一点。我需要地图仅在鼠标启动后才调整大小,否则它会滞后,并在您非常缓慢地调整窗口大小时尝试绘制自己一百万次。
等待计时器是一个非常非常糟糕的主意,很简单,它是一种启发式方法,您在猜测调整大小操作何时完成。
更好的想法是从方法派生一个类WindowsFormsHost并覆盖该WndProc方法,处理WM_SIZE消息。这是在大小操作完成时发送到窗口的消息(与WM_SIZING在此过程中发送的消息相反)。
您还可以处理WM_SIZING消息,而不是在收到此消息时调用基本实现WndProc,以防止消息被处理并让地图一直重绘自身。
WndProc类上的方法的文档Control显示了如何覆盖WndProc方法:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc(VS.71).aspx
尽管它是针对不同的班级,但它是完全相同的校长。
此外,您将需要WM_SIZING和WM_SIZE常量的值,您可以在此处找到:
http://www.pinvoke.net/default.aspx/Enums/WindowsMessages.html
请注意,您不需要上面链接中的所有内容,只需要这两个值的声明:
/// <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;
根据这里的建议:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8453ab09-ce0e-4e14-b30b-3244b51c13c4
他们建议使用计时器,并且每次触发 SizeChanged 事件时,您只需重新启动计时器。这样,计时器就不会一直调用“Tick”来检查尺寸是否发生了变化——每次尺寸变化时,计时器只会关闭一次。也许不太理想,但我不必处理任何低级 Windows 的东西。这种方法也适用于任何 wpf 用户控件,而不仅仅是 wpf 窗口。
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
//...
}