make a WPF Popup not screen bound

后端 未结 2 1326
醉酒成梦
醉酒成梦 2021-01-18 02:02

The default behavior of a Popup is if it is placed where it would extend beyond the edge of the screen, the Popup will reposition itself. Is there a way to turn this behavio

相关标签:
2条回答
  • 2021-01-18 02:32

    If you want the popup to behave more like a Window, I'd just make a Window instead of a Popup.

    Having a popup that doesn't position itself like a standard popup, and allows you to drag it around the screen, just seems like a recipe for low usability and confusion.

    0 讨论(0)
  • 2021-01-18 02:43

    Just use interop to move your popups (drag them)

    Here is code for Thumb which will track the drag process

    region Thumb

        private Thumb mThumb = null;
        public Thumb Thumb
        {
            get { return mThumb; }
            set
            {
                if (mThumb != value)
                {
                    if (mThumb != null)
                    {
                        DetachThumb();
                    }
                    mThumb = value;
                    if (mThumb != null)
                    {
                        AttachThumb();
                    }
                }
            }
        }
    
        private void AttachThumb()
        {
            Thumb.DragStarted += Thumb_DragStarted;
            Thumb.DragDelta += Thumb_DragDelta;
            Thumb.DragCompleted += Thumb_DragCompleted;
        }
    
        private void DetachThumb()
        {
            Thumb.DragStarted -= Thumb_DragStarted;
            Thumb.DragDelta -= Thumb_DragDelta;
            Thumb.DragCompleted -= Thumb_DragCompleted;
        }
    
        private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
        {
            mIsThumbDragging = true;
            mPreviousDiffX = 0;
            mPreviousDiffY = 0;
        }
    
        private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            if (mIsMoving)
            {
                return;
            }
            mIsMoving = true;
            try
            {
                if (mIsThumbDragging)
                {
                    var doubleDetaX = e.HorizontalChange + mPreviousDiffX;
                    var doubleDetaY = e.VerticalChange + mPreviousDiffY;
    
                    var deltaX = (int)doubleDetaX;
                    var deltaY = (int)doubleDetaY;
    
                    mPreviousDiffX = (double)deltaX - doubleDetaX;
                    mPreviousDiffY = (double)deltaY - doubleDetaY;
    
                    HostPopup.Move(deltaX, deltaY);
                }
            }
            finally
            {
                mIsMoving = false;
            }
        }
    
        private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            mIsThumbDragging = false;
        }
    
        #endregion
    

    The HostPopup class is subclass of Popup, and it hase the following methods using interop to move the window:

        [DllImport("user32.dll", SetLastError = true)]
        internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    
         [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
        
        internal void Move(int deltaX, int deltaY)
        {
            if (mIsMoving)
            {
                return;
            }
            mIsMoving = true;
            try
            {
                if (Child == null)
                    return;
    
                var hwndSource = (PresentationSource.FromVisual(Child)) as HwndSource;
    
                if (hwndSource == null)
                    return;
                var hwnd = hwndSource.Handle;
    
                RECT rect;
    
                if (!GetWindowRect(hwnd, out rect))
                    return;
    
                MoveWindow(hwnd, rect.Left + deltaX, rect.Top + deltaY, (int)Width, (int)Height, true);
            }
            finally
            {
                mIsMoving = false;
            }
        }
    
    0 讨论(0)
提交回复
热议问题