问题的本质是:WPF 窗口有一个自定义标头而不是标准标头。
<Window ...
WindowStyle="None"/>
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid MouseLeftButtonDown="DragMove_MouseLeftButtonDown"
x:Name="HeaderGrid">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock></TextBlock>
<Button x:Name="btnMinimize" Content="🗕" Style="{StaticResource HeaderButton}"
Click="btnMinimize_Click"
/>
<Button x:Name="btnMaximize" Content="🗖" Style="{StaticResource HeaderButton}"
Click="btnMaximize_Click"
/>
<Button x:Name="btnClose" Content="❌" Style="{StaticResource HeaderButton}"
FontWeight="Light"
FontSize="16"
Click="btnClose_Click"
Margin="0 0 5 0"
/>
</StackPanel>
</Grid>
我们需要重现标准窗口标题的行为。也就是说,您可以拖动它,并且在窗口最大化的情况下,通过单击它,它会恢复到正常大小并位于鼠标光标下方。一台显示器一切正常。
private void DragMove_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
System.Windows.Point mousePosition = Mouse.GetPosition(this);
Top = mousePosition.Y;
Left = mousePosition.X - (Width / 2) + (1920 * GetCurrentScreenNumber());
}
DragMove();
}
public int GetCurrentScreenNumber()
{
System.Drawing.Point cursorPosition = System.Windows.Forms.Control.MousePosition;
Screen screen = Screen.FromPoint(cursorPosition);
return Array.IndexOf(Screen.AllScreens, screen);
}
对于两个人来说,这种方法的一切都会变得更加复杂。到目前为止,我已经能够在主显示器位于左侧的情况下实现两个显示器的相对正确的操作。
但如果有 3 个或更多屏幕怎么办?是否有任何选项可以确定光标坐标不是当前屏幕的相对坐标,而是绝对坐标?毕竟,给出的示例效果很好,这意味着存在某种屏幕坐标的绝对网格?我怎样才能从中获取坐标?或者还有其他方法可以解决这个问题吗?
PS:在WPF中,据我了解,没有获取鼠标坐标的机制,你必须从Winforms中拖动它们?
感谢 @EvgeniyZ 的提示,我们能够使用 WindowChrome 类实现所需的行为。为了能够单击标题中的按钮,请使用按钮属性 WindowChrome.IsHitTestVisibleInChrome="True" 适用于任意数量和位置的监视器。允许您创建完全自定义的标题,例如夜间主题。
标题按钮方法代码: