WPF Window Drag / Move Border

just wondering, do you know of any way to adjust the transition border for a window?

It would be nice to have these properties:

Me.MinLeft = 10
Me.MinTop = 10
Me.MaxLeft = 150
Me.MaxTop = 150

These are the created properties, btw , which would be nice to have.

I know that maybe I can set the timer to shoot in 10 seconds and check left and top, and then move it if it runs out. But it would be more elegant if the window acted as if it had hit the wall and could not move on, for example, moving to the edge of the screen or something like that.

Edit: Something seems vaguely, the point I'm trying to make is in the paragraph above, drag and drop, not redistribution.

+1
source share
4 answers

, , , , :

Private Sub myWindow_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged

    Dim primaryBounds As System.Drawing.Rectangle = Windows.Forms.Screen.PrimaryScreen.Bounds
    Dim windowBounds As System.Drawing.Rectangle = New System.Drawing.Rectangle(CInt(Me.Left), CInt(Me.Top), CInt(Me.Width), CInt(Me.Height))

    If (windowBounds.Left < 0) Then
        windowBounds = New System.Drawing.Rectangle(0, windowBounds.Top, windowBounds.Width, windowBounds.Height)
    ElseIf (windowBounds.Right > primaryBounds.Right) Then
        windowBounds = New System.Drawing.Rectangle(primaryBounds.Right - windowBounds.Width, windowBounds.Top, windowBounds.Width, windowBounds.Height)
    End If

    If (windowBounds.Top < 0) Then
        windowBounds = New System.Drawing.Rectangle(windowBounds.Left, 0, windowBounds.Width, windowBounds.Height)
    ElseIf (windowBounds.Bottom > primaryBounds.Bottom) Then
        windowBounds = New System.Drawing.Rectangle(windowBounds.Left, primaryBounds.Bottom - windowBounds.Height, windowBounds.Width, windowBounds.Height)
    End If

    Me.Left = windowBounds.Left
    Me.Top = windowBounds.Top

End Sub

( ), , .

+2

"", , , , Window_SourceInitialized SourceInitialized event , .

, .

internal enum WM
{
   WINDOWPOSCHANGING = 0x0046,
}

[StructLayout(LayoutKind.Sequential)]
internal struct WINDOWPOS
{
   public IntPtr hwnd;
   public IntPtr hwndInsertAfter;
   public int x;
   public int y;
   public int cx;
   public int cy;
   public int flags;
}

private void Window_SourceInitialized(object sender, EventArgs ea)
{
   HwndSource hwndSource = (HwndSource)HwndSource.FromVisual((Window)sender);
   hwndSource.AddHook(DragHook);
}

private static IntPtr DragHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handeled)
{
   switch ((WM)msg)
   {
      case WM.WINDOWPOSCHANGING:
      {
          WINDOWPOS pos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));
          if ((pos.flags & (int)SWP.NOMOVE) != 0)
          {
              return IntPtr.Zero;
          }

          Window wnd = (Window)HwndSource.FromHwnd(hwnd).RootVisual;
          if (wnd == null)
          {
             return IntPtr.Zero;
          }

          bool changedPos = false;

          // ***********************
          // Here you check the values inside the pos structure
          // if you want to override tehm just change the pos
          // structure and set changedPos to true
          // ***********************

          if (!changedPos)
          {
             return IntPtr.Zero;
          }

          Marshal.StructureToPtr(pos, lParam, true);
          handeled = true;
       }
       break;
   }

   return IntPtr.Zero;
}
+3

WPF.

:

  • Window.MaxWidth
  • Window.MaxHeight

, WinForm.

0

Perhaps you could handle PreviewMouseMove(either an event, or override the appropriate protected method) and set it e.Handled = truewhenever the mouse movement causes the window to move outside the area you want to limit.

This seems like the most logical way, similar to WPF.

0
source

Source: https://habr.com/ru/post/1790555/


All Articles