使WPF弹出窗口不受屏幕限制

Popup的默认行为是,如果它被放置在超出屏幕边缘的位置,Popup将重新定位自身。 有没有办法解决这个问题?

我有一个用户可以在屏幕上拖动的Popup。 但是,当它到达边缘时会卡住。 它会卡在边缘并停留在那里,直到鼠标被拖离边缘。 此外,我有两个显示器,当Popup被拖到边缘时,两个显示器共享我闪烁。 弹出窗口在两个监视器之间闪烁。

只需使用互操作来移动弹出窗口(拖动它们)

这是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 

HostPopup类是Popup的子类,它使用interop来移动窗口,它使用以下方法:

  [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; } } 

如果你希望弹出窗口的行为更像Window,我只需要创建一个Window而不是Popup。

有一个弹出窗口没有像标准弹出窗口那样定位,并允许你将它拖动到屏幕上,这似乎是低可用性和混乱的一个秘诀。