使用多个监视器还原窗口大小/位置 [英] Restoring Window Size/Position With Multiple Monitors
问题描述
许多关于恢复WinForm位置和大小的帖子。
Many posts around about restoring a WinForm position and size.
示例:
- www.stackoverflow.com/questions/92540/save-and -restore-form-position-and-size
- www.codeproject.com/KB/dialog/restoreposition.aspx?fid=1249382& df = 90& mpp = 25& noise = 3& sort = Position& view = Quick& select = 2595746
- www.stackoverflow.com/questions/92540/save-and-restore-form-position-and-size
- www.codeproject.com/KB/dialog/restoreposition.aspx?fid=1249382&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2595746
但是我还没有找到可以在多台监视器上执行此操作的代码。
But I have yet to find code to do this with multiple monitors.
也就是说,如果我用监视器2上的窗口关闭.NET Winform应用程序,则需要它将窗口的大小,位置和状态保存为应用程序设置,以便稍后在我重新启动应用程序时可以将其还原到监视器2。就像上面的代码项目示例一样,如果它包括一些完整性检查,那就好了,就像保存的位置大部分在屏幕外一样,它可以修复它。或者,如果保存的位置位于不再存在的显示器上(例如,现在我的笔记本电脑本身就没有第二台显示器),那么它将正确地移动到显示器1。
That is, if I close my .NET Winform app with the window on monitor 2, I want it to save the windows size, location, and state to the application settings, so it could later restore to monitor 2 when I restart the app. It would be nice if, like in the codeproject example above, it includes some sanity checks, as in if the saved location is mostly off-screen it "fixes" it. Or if the saved location is on a monitor that is no longer there (e.g. my laptop is now by itself without my second monitor) then it correctly moves it to monitor 1.
有任何想法吗?
我的环境:C#、. NET 3.5或更低版本,VS2008
My environment: C#, .NET 3.5 or below, VS2008
推荐答案
VVS提供的答案很有帮助!不过,我发现了两个小问题,因此我将这些修订版本重新发布到他的大部分代码中:
The answer provided by VVS was a great help! I found two minor issues with it though, so I am reposting the bulk of his code with these revisions:
(1)应用程序第一次运行时,该表单以正常状态打开,但其大小使其仅显示为标题栏。我在构造函数中添加了一个条件来解决此问题。
(1) The very first time the application runs, the form is opened in a Normal state but is sized such that it appears as just a title bar. I added a conditional in the constructor to fix this.
(2)如果在最小化或最大化时关闭了应用程序,则OnClosing中的代码无法记住窗口的尺寸处于正常状态。 (我现在已注释掉的三行代码似乎是合理的,但由于某些原因无法正常工作。)幸运的是,我之前已经解决了这个问题,并将该代码包含在代码的新区域中。跟踪窗口状态,而不是等待关闭。
(2) If the application is closed while minimized or maximized the code in OnClosing fails to remember the dimensions of the window in its Normal state. (The 3 lines of code--which I have now commented out--seems reasonable but for some reason just does not work.) Fortunately I had previously solved this problem and have included that code in a new region at the end of the code to track window state as it happens rather than wait for closing.
有了这两个修复程序,我已经测试了:
With these two fixes in place, I have tested:
A。在正常状态下关闭-恢复为相同的大小/位置和状态
A. closing in normal state--restores to same size/position and state
B。在最小化状态下关闭-恢复到具有最后一个正常大小/位置的正常状态
B. closing in minimized state--restores to normal state with last normal size/position
C。在最大化状态下关闭-恢复到最大化状态,并在以后调整为正常状态时记住其最后的大小/位置。
C. closing in maximized state--restores to maximized state and remembers its last size/position when one later adjusts to normal state.
D。在监视器2上关闭-恢复到监视器2。
D. closing on monitor 2--restores to monitor 2.
E。在监视器2上关闭然后断开监视器2的连接,将其恢复到监视器1上的相同位置
E. closing on monitor 2 then disconnecting monitor 2--restores to same position on monitor 1
David:您的代码使我几乎毫不费力地达到了D点和E点您是否为我的问题提供了解决方案,您是否在完整的程序中提供了解决方案,所以我将其粘贴到Visual Studio的几秒钟内就可以启动并运行。
David: your code allowed me to achieve points D and E almost effortlessly--not only did you provide a solution for my question, you provided it in a complete program so I had it up and running almost within seconds of pasting it into Visual Studio. So a big thank you for that!
public partial class MainForm : Form
{
bool windowInitialized;
public MainForm()
{
InitializeComponent();
// this is the default
this.WindowState = FormWindowState.Normal;
this.StartPosition = FormStartPosition.WindowsDefaultBounds;
// check if the saved bounds are nonzero and visible on any screen
if (Settings.Default.WindowPosition != Rectangle.Empty &&
IsVisibleOnAnyScreen(Settings.Default.WindowPosition))
{
// first set the bounds
this.StartPosition = FormStartPosition.Manual;
this.DesktopBounds = Settings.Default.WindowPosition;
// afterwards set the window state to the saved value (which could be Maximized)
this.WindowState = Settings.Default.WindowState;
}
else
{
// this resets the upper left corner of the window to windows standards
this.StartPosition = FormStartPosition.WindowsDefaultLocation;
// we can still apply the saved size
// msorens: added gatekeeper, otherwise first time appears as just a title bar!
if (Settings.Default.WindowPosition != Rectangle.Empty)
{
this.Size = Settings.Default.WindowPosition.Size;
}
}
windowInitialized = true;
}
private bool IsVisibleOnAnyScreen(Rectangle rect)
{
foreach (Screen screen in Screen.AllScreens)
{
if (screen.WorkingArea.IntersectsWith(rect))
{
return true;
}
}
return false;
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
// only save the WindowState if Normal or Maximized
switch (this.WindowState)
{
case FormWindowState.Normal:
case FormWindowState.Maximized:
Settings.Default.WindowState = this.WindowState;
break;
default:
Settings.Default.WindowState = FormWindowState.Normal;
break;
}
# region msorens: this code does *not* handle minimized/maximized window.
// reset window state to normal to get the correct bounds
// also make the form invisible to prevent distracting the user
//this.Visible = false;
//this.WindowState = FormWindowState.Normal;
//Settings.Default.WindowPosition = this.DesktopBounds;
# endregion
Settings.Default.Save();
}
# region window size/position
// msorens: Added region to handle closing when window is minimized or maximized.
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
TrackWindowState();
}
protected override void OnMove(EventArgs e)
{
base.OnMove(e);
TrackWindowState();
}
// On a move or resize in Normal state, record the new values as they occur.
// This solves the problem of closing the app when minimized or maximized.
private void TrackWindowState()
{
// Don't record the window setup, otherwise we lose the persistent values!
if (!windowInitialized) { return; }
if (WindowState == FormWindowState.Normal)
{
Settings.Default.WindowPosition = this.DesktopBounds;
}
}
# endregion window size/position
}
这篇关于使用多个监视器还原窗口大小/位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!