确定打开的WPF窗口在任何监视器上是否可见 [英] Determine if an open WPF window is visible on any monitor
问题描述
有没有一种方法可以确定打开的WPF窗口当前在任何台式机连接的显示器中是否可见? 可见是指窗口的边界矩形与任何监视器的桌面矩形相交。
Is there a way to determine if an open WPF window is currently visible in any of the desktop's connected monitors? By visible I mean that the window's bounds rectangle intersects with the desktop rectangle of any of the monitors.
我需要此功能来确定是否需要重新放置窗口,因为监视器配置(工作区域范围,监视器计数)在应用程序重新启动之间进行了更改(这节省了窗口位置)。
I need this functionality to determine if a window needs to be repositioned because the monitor configuration (working areas bounds, monitor count) changed between restarts of my application (which saves window positions).
我想出了下面的代码,看来工作,但有几个问题:
I have come up with the code below and it seems to work, but it has several problems:
- 我需要引用Windows窗体。
- 我需要桌面的DPI设置,并将窗口形式的实际像素转换为WPF虚拟像素。
- 我需要一个已经存在的实际Visual实例
您知道一种解决方案可以摆脱上述3个问题中的部分或全部吗? p>
Do you know of a solution that gets rid of some or all of the 3 issues above?
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
internal static class Desktop
{
private static Size dpiFactor = new Size(1.0, 1.0);
private static bool isInitialized;
public static IEnumerable<Rect> WorkingAreas
{
get
{
return
Screen.AllScreens.Select(
screen =>
new Rect(
screen.WorkingArea.Left * dpiFactor.Width,
screen.WorkingArea.Top * dpiFactor.Height,
screen.WorkingArea.Width * dpiFactor.Width,
screen.WorkingArea.Height * dpiFactor.Height));
}
}
public static void TryInitialize(Visual visual)
{
if (isInitialized)
{
return;
}
var ps = PresentationSource.FromVisual(visual);
if (ps == null)
{
return;
}
var ct = ps.CompositionTarget;
if (ct == null)
{
return;
}
var m = ct.TransformToDevice;
dpiFactor = new Size(m.M11, m.M22);
isInitialized = true;
}
}
(初始化的)桌面
类:
private bool IsLocationValid(Rect windowRectangle)
{
foreach (var workingArea in Desktop.WorkingAreas)
{
var intersection = Rect.Intersect(windowRectangle, workingArea);
var minVisible = new Size(10.0, 10.0);
if (intersection.Width >= minVisible.Width &&
intersection.Height >= minVisible.Height)
{
return true;
}
}
return false;
}
更新
Update
使用虚拟屏幕( SystemParameters.VirtualScreen *
)不起作用,因为使用多个监视器时,桌面不是一个简单的矩形。它可能是一个多边形。虚拟屏幕中将存在盲点,因为
Using the virtual screen (SystemParameters.VirtualScreen*
) does not work because when using multiple monitors the "desktop" is not a simple rectangle. It might be a polygon. There will be blind spots in the virtual screen because
- 连接的屏幕可以具有不同的分辨率
- 您可以配置每个屏幕的位置。
推荐答案
我们用于执行类似操作的代码使用来自 SystemParameters 的信息,尤其是SystemParameter.VirtualScreenLeft,顶部,宽度和高度。
The code we use to do something similar uses information from SystemParameters, in particular SystemParameter.VirtualScreenLeft, Top, Width and Height.
如果我们保存了位置和大小,则可以确定窗口是否超出了这样的范围:
If we have a saved Location and Size then we determine if the window is out of bounds like this:
bool outOfBounds =
(location.X <= SystemParameters.VirtualScreenLeft - size.Width) ||
(location.Y <= SystemParameters.VirtualScreenTop - size.Height) ||
(SystemParameters.VirtualScreenLeft +
SystemParameters.VirtualScreenWidth <= location.X) ||
(SystemParameters.VirtualScreenTop +
SystemParameters.VirtualScreenHeight <= location.Y);
这篇关于确定打开的WPF窗口在任何监视器上是否可见的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!