Popup的默认行为是,如果它被放置在超出屏幕边缘的位置,Popup将重新定位自身。有没有办法解决这个问题?
我有一个Popup,用户可以在屏幕上拖动。但是,当它到达边缘时会卡住。它会卡在边缘并停留在那里,直到鼠标被拖离边缘。此外,我有两个监视器,当弹出窗口被拖到边缘时,两个监视器共享我闪烁。弹出窗口在两个监视器之间闪烁。
答案 0 :(得分:3)
只需使用互操作来移动弹出窗口(拖动它们)
这是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;
}
}
答案 1 :(得分:2)
如果你希望弹出窗口的行为更像Window,我只需要创建一个Window而不是Popup。
弹出窗口不会像标准弹出窗口那样定位,并允许您将其拖动到屏幕上,这似乎是低可用性和混乱的一种方法。