Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make a WPF Popup not screen bound

Tags:

c#

wpf

popup

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 behavior off?

I have a Popup that the user can drag around the screen. However, when it gets to the edges it gets stuck. It gets stuck on the edge and stays there until the mouse is dragged far from the edge. Also, I have two monitors and when the Popup is dragged to the edge the two monitors share I get flickering. The Popup flickers between the two monitors.

like image 758
Dan Vogel Avatar asked Oct 30 '09 23:10

Dan Vogel


2 Answers

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;
        }
    }
like image 198
Kirill Chilingarashvili Avatar answered Sep 28 '22 14:09

Kirill Chilingarashvili


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.

like image 21
Reed Copsey Avatar answered Sep 28 '22 16:09

Reed Copsey