Reputation: 2219
I've got a windows forms map in a WindowsFormsHost, and I need it to resize with the window.
I'm just not sure what event to listen to, to do this. I need the map to only resize once the mouse is up, otherwise it lags out, and tries drawing itself a million times when you resize a window really slowly.
Upvotes: 5
Views: 5646
Reputation: 74530
Waiting on a timer is a very, very bad idea, quite simply, it's a heuristic and you are guessing when the resize operation is done.
A better idea would be to derive a class from WindowsFormsHost
and override the WndProc
method, handling the WM_SIZE
message. This is the message that is sent to a window when the size operation is complete (as opposed to WM_SIZING
, which is sent during the process).
You can also handle the WM_SIZING
message, and not call the base implementation of WndProc
when you get this message, to prevent the message from being processed and having the map redraw itself all those times.
The documentation for the WndProc
method on the Control
class shows how to override WndProc
method:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc(VS.71).aspx
Even though it is for a different class, it's the same exact principal.
Additionally, you will need the values for the WM_SIZING
and WM_SIZE
constants, which you can find here:
http://www.pinvoke.net/default.aspx/Enums/WindowsMessages.html
Note that you don't need everything from the link above, just the declarations for those two values:
/// <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;
Upvotes: 7
Reputation: 15227
Per the suggestion here:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8453ab09-ce0e-4e14-b30b-3244b51c13c4
They suggest to use timer and everytime the SizeChanged event fires, you simply restart the timer. That way the timer isn't calling "Tick" all the time to check if the size has changed - the timer only goes off once per size change. Maybe less than ideal, but I don't have to deal with any low level windows stuff. This approach works for any wpf user control too, not just wpf windows.
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
//...
}
Upvotes: -3