Is it possible to make a Window
such that when it's resized in height by the user, it increments and decrements by 10? Sort of like snapping resize.
Here is an example of how this can be done:
using System;
using System.Runtime.InteropServices;
using System.Windows.Interop;
namespace DeleteMeWPF {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow {
public MainWindow() {
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e) {
base.OnSourceInitialized(e);
IntPtr handle = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(this.WindowProc));
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT {
public int left;
public int top;
public int right;
public int bottom;
}
private const int WM_SIZING = 0x0214;
private const int WMSZ_BOTTOM = 6;
private const int WMSZ_BOTTOMLEFT = 7;
private const int WMSZ_BOTTOMRIGHT = 8;
private const int WMSZ_LEFT = 1;
private const int WMSZ_RIGHT = 2;
private const int WMSZ_TOP = 3;
private const int WMSZ_TOPLEFT = 4;
private const int WMSZ_TOPRIGHT = 5;
private const int SnappingIncrement = 100;
private const int SnappingThresholdWidth = 300;
private const int SnappingThresholdHeight = 400;
private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
switch (msg) {
case WM_SIZING:
RECT bounds = (RECT)Marshal.PtrToStructure(lParam, typeof(RECT));
int width = bounds.right - bounds.left;
int height = bounds.bottom - bounds.top;
switch (wParam.ToInt32()) {
case WMSZ_BOTTOM:
if (height > SnappingThresholdHeight)
bounds.bottom = bounds.top + ((int)((double)height / (double)SnappingIncrement) * SnappingIncrement);
break;
case WMSZ_BOTTOMLEFT:
if (height > SnappingThresholdHeight)
bounds.bottom = bounds.top + ((int)((double)height / (double)SnappingIncrement) * SnappingIncrement);
if (width > SnappingThresholdWidth)
bounds.left = bounds.right - ((int)((double)width / (double)SnappingIncrement) * SnappingIncrement);
break;
case WMSZ_BOTTOMRIGHT:
if (height > SnappingThresholdHeight)
bounds.bottom = bounds.top + ((int)((double)height / (double)SnappingIncrement) * SnappingIncrement);
if (width > SnappingThresholdWidth)
bounds.right = bounds.left + ((int)((double)width / (double)SnappingIncrement) * SnappingIncrement);
break;
case WMSZ_LEFT:
if (width > SnappingThresholdWidth)
bounds.left = bounds.right - ((int)((double)width / (double)SnappingIncrement) * SnappingIncrement);
break;
case WMSZ_RIGHT:
if (width > SnappingThresholdWidth)
bounds.right = bounds.left + ((int)((double)width / (double)SnappingIncrement) * SnappingIncrement);
break;
case WMSZ_TOP:
if (height > SnappingThresholdHeight)
bounds.top = bounds.bottom - ((int)((double)height / (double)SnappingIncrement) * SnappingIncrement);
break;
case WMSZ_TOPLEFT:
if (width > SnappingThresholdWidth)
bounds.left = bounds.right - ((int)((double)width / (double)SnappingIncrement) * SnappingIncrement);
if (height > SnappingThresholdHeight)
bounds.top = bounds.bottom - ((int)((double)height / (double)SnappingIncrement) * SnappingIncrement);
break;
case WMSZ_TOPRIGHT:
if (width > SnappingThresholdWidth)
bounds.right = bounds.left + ((int)((double)width / (double)SnappingIncrement) * SnappingIncrement);
if (height > SnappingThresholdHeight)
bounds.top = bounds.bottom - ((int)((double)height / (double)SnappingIncrement) * SnappingIncrement);
break;
}
Marshal.StructureToPtr(bounds, lParam, false);
break;
}
return IntPtr.Zero;
}
}
}
This uses increments of 100 to really illustrate the "snapping" effect. In addition, you can adjust the snapping thresholds, which ensure the snapping only takes effect when the size is above a given width/height.
The old Win32 Listbox had a setting to prevent that. Note that that was solving the problem from the other end.
But take a look at a few established TreeViews first. Like Visual Studio, Tools Options.
I don't think you should be modifying the behaviour of std UI controls this way. Users will only be frustrated if your TV acts 'differently'. They won't call it 'better'.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With