![](/img/trans.png)
[英]How to implement drag move snapping to screen edges and corners for WPF Window?
[英]WPF Window Drag/Move Boundary
只是好奇是否知道為窗口設置拖動邊界的任何方法?
具有這些屬性將是很好的:
Me.MinLeft = 10
Me.MinTop = 10
Me.MaxLeft = 150
Me.MaxTop = 150
這些是由屬性btw組成的 ,很高興擁有。
我知道我可能可以設置一個計時器,使其每十秒觸發一次,檢查左側和頂部,如果結束則將其移回。 但是,讓窗口像打到牆一樣,又不能走得更遠,比如移動到屏幕的邊緣或類似的東西,會更加優雅。
編輯:某處似乎有些混亂,我要說明的是在上面的段落中,拖動而不是重新調整大小。
這是創建此功能所需要的“魔術”,所有您需要做的就是將Window_SourceInitialized方法設置為窗口的SourceInitialized事件,並在大注釋所在的位置插入邏輯。
我從多個來源組合了此代碼,因此其中可能存在一些語法錯誤。
internal enum WM
{
WINDOWPOSCHANGING = 0x0046,
}
[StructLayout(LayoutKind.Sequential)]
internal struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public int flags;
}
private void Window_SourceInitialized(object sender, EventArgs ea)
{
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual((Window)sender);
hwndSource.AddHook(DragHook);
}
private static IntPtr DragHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handeled)
{
switch ((WM)msg)
{
case WM.WINDOWPOSCHANGING:
{
WINDOWPOS pos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));
if ((pos.flags & (int)SWP.NOMOVE) != 0)
{
return IntPtr.Zero;
}
Window wnd = (Window)HwndSource.FromHwnd(hwnd).RootVisual;
if (wnd == null)
{
return IntPtr.Zero;
}
bool changedPos = false;
// ***********************
// Here you check the values inside the pos structure
// if you want to override tehm just change the pos
// structure and set changedPos to true
// ***********************
if (!changedPos)
{
return IntPtr.Zero;
}
Marshal.StructureToPtr(pos, lParam, true);
handeled = true;
}
break;
}
return IntPtr.Zero;
}
毫無疑問,Nir的答案會花一些時間來實現它,因此我可以用以下代碼做一些我想做的事情:
Private Sub myWindow_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
Dim primaryBounds As System.Drawing.Rectangle = Windows.Forms.Screen.PrimaryScreen.Bounds
Dim windowBounds As System.Drawing.Rectangle = New System.Drawing.Rectangle(CInt(Me.Left), CInt(Me.Top), CInt(Me.Width), CInt(Me.Height))
If (windowBounds.Left < 0) Then
windowBounds = New System.Drawing.Rectangle(0, windowBounds.Top, windowBounds.Width, windowBounds.Height)
ElseIf (windowBounds.Right > primaryBounds.Right) Then
windowBounds = New System.Drawing.Rectangle(primaryBounds.Right - windowBounds.Width, windowBounds.Top, windowBounds.Width, windowBounds.Height)
End If
If (windowBounds.Top < 0) Then
windowBounds = New System.Drawing.Rectangle(windowBounds.Left, 0, windowBounds.Width, windowBounds.Height)
ElseIf (windowBounds.Bottom > primaryBounds.Bottom) Then
windowBounds = New System.Drawing.Rectangle(windowBounds.Left, primaryBounds.Bottom - windowBounds.Height, windowBounds.Width, windowBounds.Height)
End If
Me.Left = windowBounds.Left
Me.Top = windowBounds.Top
End Sub
這使被拖動的窗口停留在主屏幕(整個窗口)內,但是您可以輕松地將邊界更改為所需的任何值。
為此,WPF的窗口具有依賴項屬性。
他們來了:
這些屬性將限制Window的大小,就像WinForm的Form一樣。
也許您可以處理PreviewMouseMove
(事件或重寫相應的受保護方法),並在每次鼠標移動會使窗口移至您要限制窗口的區域之外時將e.Handled = true
設置。
這似乎是最符合邏輯的,類似WPF的方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.