How to resize WPF window in steps?

Is it possible to make Window so that when the user resizes the user, it increases and decreases by 10? Like a change in binding.

+4
source share
6 answers

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; } } } 

Here, step 100 is used to truly illustrate the β€œsnap” effect. In addition, you can configure snap thresholds that ensure that snap only works when the size exceeds a given width / height.

+4
source

The old Win32 Listbox had a setup to prevent this. Please note that this is a solution to the problem from the other end.

But first, take a look at a few installed TreeViews. Like Visual Studio, Tool Options.

I don't think you should change the behavior of std UI controls in this way. Users will be disappointed if your TV operates "differently." They will not call it "better."

+3
source

It cannot be very nice for the window to become the size the user did not want ... what happens if they maximize the window, and this is not a multiple of 10? Can you save the other borders of the window in the same place if they dragged the top edge of the window?

Instead, I will focus on TreeView: create a container that implements MeasureOverride and call the base.MeasureOverride implementation, and when it gets this result, rounds the values ​​down (always down) to a multiple of 10. The rest of the contents of your window will get a different space, depending on window size, but just make sure you have something in your layout that will stretch to take an extra 0-9 pixels.

+3
source

Ok, usually you need to handle the Resize / Resize event and then round up or down to a multiple of ten or something like that.

However, in WPF, you will probably have to resort to a hacker using behavior.

See this article for a description of what you need to do to access the resize event.

+1
source

You can add a SizeChangedEventHandler element to the SizeChanged event. Then in your delegate method, resize manually.

Although I think it would be difficult to understand how much this has changed if you did not record it somewhere.

+1
source

Well, I was going to say: "In contrast, and without writing a dirty twist code? I don’t know."

... I will stick to this xD

0
source

All Articles