Make the window draggable within a specific WPF border

I have a wpf child window that I allow drag and drop using the DragMove () method. However, I need to allow the window to be dragged only within its control of the parent window.

Can anyone suggest a way to achieve this? Thank!

+3
source share
1 answer

There are two ways to do this.

Using LocationEnded

If you are handling this event, you can change the top or left side within the owner window. eg

    private void Window_LocationChanged(object sender, EventArgs e)
    {

        if (this.Left < this.Owner.Left)
            this.Left = this.Owner.Left;

        //... also right top and bottom
        //
    }

, , , , .

AddHook

, Windows . .

, AddHook

, hook

  //In Window_Loaded the handle is there (earlier its null) so this is good time to add the handler 

   private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        WindowInteropHelper helper = new WindowInteropHelper(this);
        HwndSource.FromHwnd(helper.Handle).AddHook(HwndSourceHookHandler);
    } 

. lParam , . lParam . , . , .

 private IntPtr HwndSourceHookHandler(IntPtr hwnd, int msg, IntPtr wParam,
    IntPtr lParam, ref bool handled)
        {


const int WM_MOVING = 0x0216;
        const int WM_MOVE = 0x0003;


        switch (msg)
        {
            case WM_MOVING:
                {


                   //read the lparm ino a struct

                    MoveRectangle rectangle = (MoveRectangle)Marshal.PtrToStructure(
                      lParam, typeof(MoveRectangle));


                     //

                    if (rectangle.Left < this.Owner.Left)
                    {
                        rectangle.Left = (int)this.Owner.Left;
                        rectangle.Right = rectangle.Left + (int)this.Width;
                    }



                    Marshal.StructureToPtr(rectangle, lParam, true);

                    break;
                }
            case WM_MOVE:
                {
                   //Do the same thing as WM_MOVING You should probably enacapsulate that stuff so don'tn just copy and paste

                    break;
                }


        }

        return IntPtr.Zero;

    }

lParam

  [StructLayout(LayoutKind.Sequential)]
    //Struct for Marshalling the lParam
    public struct MoveRectangle
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;

    }

, , .

+5

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


All Articles