我在另一个讨论论坛上找到了答案(我不记得是哪一个,否则我会给予他们信任)。结果比我想象的要容易。如果您挂钩 WM_MOVING 消息(我这样做,在加载窗口时下方),您可以在窗口移动之前拦截移动并限制窗口的位置。
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WindowInteropHelper helper = new WindowInteropHelper(this);
HwndSource.FromHwnd(helper.Handle).AddHook(HwndMessageHook);
InitialWindowLocation = new Point(this.Left, this.Top);
}
// Grab the Win32 WM_MOVING message so we can intercept a move BEFORE
// it happens and constrain the child window's location.
private IntPtr HwndMessageHook(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool bHandled)
{
switch (msg)
{
// might also want to handle case WM_SIZING:
case WM_MOVING:
{
WIN32Rectangle rectangle = (WIN32Rectangle)Marshal.PtrToStructure(lParam, typeof(WIN32Rectangle));
if (rectangle.Top < 50)
{
rectangle.Top = 50;
rectangle.Bottom = 50 + (int)this.Height;
bHandled = true;
}
if (rectangle.Left < 10)
{
rectangle.Left = 10;
rectangle.Right = 10 + (int)this.Width;
bHandled = true;
}
if (rectangle.Bottom >800)
{
rectangle.Bottom = 800;
rectangle.Top = 800 - (int)this.Height;
bHandled = true;
}
// do anything to handle Right case?
if (bHandled)
{
Marshal.StructureToPtr(rectangle, lParam, true);
}
}
break;
}
return IntPtr.Zero;
}
XAML 标头如下所示:
<Window x:Class="Mockup_9.Entity11"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Mockup_9"
ShowInTaskbar="False"
Background="LightGoldenrodYellow"
Loaded="Window_Loaded"
Title="Mockup_part -" Height="540" Width="380" ResizeMode="NoResize"
Icon="/Mockup_9;component/Images/refresh-icon1.jpg">
. . . 等等