You can use either of the following options:
- You can handle WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE native messages using a HwndSourceHook which is what WinForms does for ResizeBegin and ResizeEnd events.
- Or you can use a timer, to debounce the noise of SizeChanged based on a delay.
Example 1 - WPF Window ResizeBegin and ResizeEnd events like WinForms
This technique relies on handling WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE native messages using a HwndSourceHook which is pretty similar to what WinForms does:
using System;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
namespace WpfApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer timer = new DispatcherTimer
{
Interval = new TimeSpan(0, 0, 0, 0, 500),
IsEnabled = false
};
public MainWindow()
{
InitializeComponent();
this.Loaded += (obj, args) =>
{
var handle = new WindowInteropHelper(this).Handle;
var win = HwndSource.FromHwnd(handle);
win.AddHook(new HwndSourceHook(WndProc));
};
}
private const int WM_ENTERSIZEMOVE = 0x0231;
private const int WM_EXITSIZEMOVE = 0x0232;
public event EventHandler ResizeBegin;
public event EventHandler ResizeEnd;
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_ENTERSIZEMOVE)
{
OnResizeBegin();
handled = true;
}
if (msg == WM_EXITSIZEMOVE)
{
OnResizeEnd();
handled = true;
}
return IntPtr.Zero;
}
private void OnResizeBegin()
{
this.Title = "Resize begin ...";
//Any custom logic for resize begin
}
private void OnResizeEnd()
{
this.Title = "Resize end.";
//Any custom logic for resize begin
}
}
}
Example 2 - WPF Window Debounce the SizeChanged event
In this example I've used a timer to debounce the SizeChanged event and run a logic after the resize is done. This technique relies on a custom delay (like 500 milliseconds, or anything which fits the requirement), like what is usually used in Hover event:
public partial class MainWindow : Window
{
DispatcherTimer timer = new DispatcherTimer
{
Interval = new TimeSpan(0, 0, 0, 0, 500),
IsEnabled = false
};
public MainWindow()
{
InitializeComponent();
timer.Tick += timer_Tick;
this.SizeChanged += Window_SizeChanged;
//Or if you want to handle the SizeChanged
//this.Loaded+=(obj, args) => this.SizeChanged += Window_SizeChanged;
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
this.Title = "Resizing ...";
timer.IsEnabled = true;
timer.Stop();
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
timer.IsEnabled = false;
//Resize ended (based on 500 ms debaounce time
this.Title = "Resize done.";
}
}
You can see a few more example or possible solutions here: How to catch the ending resize window?