1

I am building a WPF 4.5 Application that has controls that enable the User to "Lock" and "Unlock" the Application's Height.

In order to lock the Height, I am following this StackOverflow answer regarding setting the MinHeight and MaxHeight to the same value.

In order to unlock the Height, I set MinHeight=0 and MaxHeight=double.PositiveInfinity

This all appears to be working fine.

The problem I'm encountering that I haven't been able to solve is that when the height is "Locked", when I mouseover the right edge of the Application Window, the cursor turns into the horizontal resize cursor.

Is there a way I can disable that so that the cursor stays as the regular pointer in WPF?

I am on WPF 4.5.

I saw this post that has answers showing how to do it in Win32: WPF: Make window unresizeable, but keep the frame?.

This post is over 3 years old, and I was just wondering (hoping) maybe WPF has evolved since then.

Thank you very much in advance!

Philip

Community
  • 1
  • 1
Philip Tenn
  • 6,003
  • 8
  • 48
  • 85
  • Is your App launching a Window at startup? – Tyler Morrow Mar 06 '14 at 23:43
  • @TheRedLou Yes. My `App.xaml` specifies `StartupUri="MainWindow.xaml"`, which is a Window. – Philip Tenn Mar 07 '14 at 04:56
  • 1
    @TheRedLou Well, it was good information but it did not solve my problem. The reason is I can't set it to NoResize. I am not disabling resizing altogether, I just want to disable either horizontal resize or vertical resize (but not both). Thank you though, I did upvote your answer. – Philip Tenn Apr 19 '14 at 23:53

2 Answers2

1

On your startup Window (MainWindow.xaml), try making a binding for the Window's ResizeMode property and then modifying it to 'NoResize' when you don't want it to be resizable. To make it resizable, change it to 'CanResize'.

Hope that helps!

Tyler Morrow
  • 949
  • 8
  • 31
1

You need to set MinWidth = MaxWidth = Width = your desired width as mentioned in this StackOverflow answer regarding setting the MinHeight and MaxHeight to the same value.

In addition you need to hook the winproc for your window and process the WM_NCHITTEST message.

#region Vertical Resize Only

// ReSharper disable InconsistentNaming
private const int WM_NCHITTEST = 0x0084;
private const int HTBORDER = 18;
private const int HTBOTTOM = 15;
private const int HTBOTTOMLEFT = 16;
private const int HTBOTTOMRIGHT = 17;
private const int HTLEFT = 10;
private const int HTRIGHT = 11;
private const int HTTOP = 12;
private const int HTTOPLEFT = 13;
private const int HTTOPRIGHT = 14;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr DefWindowProc(
    IntPtr hWnd,
    int msg,
    IntPtr wParam,
    IntPtr lParam);

// ReSharper restore InconsistentNaming

#endregion Vertical Resize Only

public CanConfigurationDialog()
{
    InitializeComponent();
    Loaded += MainWindowLoaded;
}


#region Vertical Resize Only

private void MainWindowLoaded(object sender, RoutedEventArgs e)
{
    try
    {
        // Obtain the window handle for WPF application
        var mainWindowPtr = new WindowInteropHelper(this).Handle;
        var mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
        mainWindowSrc?.AddHook(WndProc);
    }
    catch (Exception)
    {
        ;
    }
}

private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    // Override the window hit test
    // and if the cursor is over a resize border,
    // return a standard border result instead.
    if (msg == WM_NCHITTEST)
    {
        handled = true;
        var htLocation = DefWindowProc(hwnd, msg, wParam, lParam).ToInt32();
        switch (htLocation)
        {
            case HTTOP:
            case HTTOPLEFT:
            case HTTOPRIGHT:
                htLocation = HTTOP;
                break;

            case HTBOTTOM:
            case HTBOTTOMLEFT:
            case HTBOTTOMRIGHT:
                htLocation = HTBOTTOM;
                break;

            case HTLEFT:
            case HTRIGHT:
                htLocation = HTBORDER;
                break;
        }

        return new IntPtr(htLocation);
    }

    return IntPtr.Zero;
}

#endregion Vertical Resize Only

This will prevent the horizontal resize cursor from being displayed! Q.E.D.