3
我有一个wpf子窗口,允许使用DragMove()方法进行拖动。 但是,我需要允许窗口只在其父窗口控件的边界内被拖动。使窗口在特定边界内可拖动WPF
任何人都可以提出一种方法来实现这一目标吗? 谢谢!
我有一个wpf子窗口,允许使用DragMove()方法进行拖动。 但是,我需要允许窗口只在其父窗口控件的边界内被拖动。使窗口在特定边界内可拖动WPF
任何人都可以提出一种方法来实现这一目标吗? 谢谢!
有两种方法可以做到这一点。
如果你处理这个事件,您可以更改顶部或左侧是所有者窗口的范围内。 例如
private void Window_LocationChanged(object sender, EventArgs e)
{
if (this.Left < this.Owner.Left)
this.Left = this.Owner.Left;
//... also right top and bottom
//
}
这是很容易写,但它违反了,因为它没有束缚它只是推窗回拖动窗口的地方,当用户放开鼠标按钮的Principle of least astonishment。
使用AddHook
正如彼得在an answer指出了一个类似的问题,你可以互操作的Windows消息和阻止拖动窗口。这具有限制实际拖动窗口的的好效果。
下面是一些示例代码,我把共同为AddHook方法
开始加载至加钩
//In Window_Loaded the handle is there (earlier its null) so this is good time to add the handler
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WindowInteropHelper helper = new WindowInteropHelper(this);
HwndSource.FromHwnd(helper.Handle).AddHook(HwndSourceHookHandler);
}
在你只想寻找移动或移动消息处理函数中的窗口。然后你会看到lParam矩形,看看它是否超出界限。如果是这样,您需要更改lParam矩形的值并将其重新编组。为了简洁起见,我只做了左侧。你仍然需要写出正确的,顶部和底部的情况。
private IntPtr HwndSourceHookHandler(IntPtr hwnd, int msg, IntPtr wParam,
IntPtr lParam, ref bool handled)
{
const int WM_MOVING = 0x0216;
const int WM_MOVE = 0x0003;
switch (msg)
{
case WM_MOVING:
{
//read the lparm ino a struct
MoveRectangle rectangle = (MoveRectangle)Marshal.PtrToStructure(
lParam, typeof(MoveRectangle));
//
if (rectangle.Left < this.Owner.Left)
{
rectangle.Left = (int)this.Owner.Left;
rectangle.Right = rectangle.Left + (int)this.Width;
}
Marshal.StructureToPtr(rectangle, lParam, true);
break;
}
case WM_MOVE:
{
//Do the same thing as WM_MOVING You should probably enacapsulate that stuff so don'tn just copy and paste
break;
}
}
return IntPtr.Zero;
}
该结构的lParam的
[StructLayout(LayoutKind.Sequential)]
//Struct for Marshalling the lParam
public struct MoveRectangle
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
最后要注意,你需要弄清楚如果子窗口被允许比父窗口做大做什么。
非常感谢康拉德。我会试试这个,让你知道。 – Dan 2011-02-08 16:32:38