只是好奇你是否知道为窗口设置拖动边界的任何方法?
拥有这些属性会很好:
Me.MinLeft = 10
Me.MinTop = 10
Me.MaxLeft = 150
Me.MaxTop = 150
这些是属性,btw ,这样会很好。
我知道我可能会设置一个定时器来启动10秒钟并检查左侧和顶部,然后如果它结束则将其移回。但是让窗户像撞墙一样更加优雅,不能走得更远,比如移动到屏幕的边缘或者类似的东西。
编辑:某处似乎有些混乱,我试图在上面的段落中拖拽,而不是重新调整大小。
答案 0 :(得分:3)
这是您需要创建此功能的“魔法”,您只需将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;
}
答案 1 :(得分:2)
我毫不怀疑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
这使得被拖动的窗口保持在主屏幕(整个窗口)内,但您可以轻松地将边界更改为您需要的任何值。
答案 2 :(得分:0)
为此目的,WPF的窗口有依赖属性。
他们是:
这些属性将限制Window的大小,就像WinForm的Form一样。
答案 3 :(得分:0)
也许您可以处理PreviewMouseMove
(事件或覆盖相应的受保护方法)并设置e.Handled = true
,只要鼠标移动会导致窗口移动到您想要约束它的区域之外。
这似乎是最合乎逻辑的WPF方式。