.NET / Windows窗体:记住窗口大小和位置
我有一个Windows窗体应用程序与一个正常的窗口。 现在,当我closures应用程序并重新启动它时,我希望主窗口显示在屏幕上的相同位置,并且与closures时的大小相同。
在Windows窗体中是否有一种简单的方法来记住屏幕位置和窗口大小(如果可能的话还有窗口状态)还是一切都必须手动完成?
您需要在应用程序设置中保存窗口位置和大小。 这里有一个很好的C# 文章来展示如何。
编辑
您可以在应用程序设置中保存几乎任何您想要的内容。 在设置网格的types列中,您可以浏览到任何.NETtypes。 WindowState在System.Windows.Forms中,并被列为FormWindowState。 还有一个FormStartPosition属性。
如果您将此代码添加到FormClosing
事件处理程序:
if (WindowState == FormWindowState.Maximized) { Properties.Settings.Default.Location = RestoreBounds.Location; Properties.Settings.Default.Size = RestoreBounds.Size; Properties.Settings.Default.Maximised = true; Properties.Settings.Default.Minimised = false; } else if (WindowState == FormWindowState.Normal) { Properties.Settings.Default.Location = Location; Properties.Settings.Default.Size = Size; Properties.Settings.Default.Maximised = false; Properties.Settings.Default.Minimised = false; } else { Properties.Settings.Default.Location = RestoreBounds.Location; Properties.Settings.Default.Size = RestoreBounds.Size; Properties.Settings.Default.Maximised = false; Properties.Settings.Default.Minimised = true; } Properties.Settings.Default.Save();
它会保存当前状态。
然后将此代码添加到您的窗体的OnLoad
处理程序:
if (Properties.Settings.Default.Maximised) { WindowState = FormWindowState.Maximized; Location = Properties.Settings.Default.Location; Size = Properties.Settings.Default.Size; } else if (Properties.Settings.Default.Minimised) { WindowState = FormWindowState.Minimized; Location = Properties.Settings.Default.Location; Size = Properties.Settings.Default.Size; } else { Location = Properties.Settings.Default.Location; Size = Properties.Settings.Default.Size; }
它会恢复最后的状态。
它甚至可以记住设置应用程序的多监视器中的哪个监视器已被最大化。
以前的解决scheme并不适合我。 玩了一段时间后,我结束了以下代码:
- 保持最大化和正常状态
- 用默认位置replace最小化状态
-
在屏幕尺寸改变的情况下(分离监视器,远程连接,…),不会让用户进入令人沮丧的状态,应用程序在屏幕之外打开。
private void MyForm_Load(object sender, EventArgs e) { if (Properties.Settings.Default.IsMaximized) WindowState = FormWindowState.Maximized; else if (Screen.AllScreens.Any(screen => screen.WorkingArea.IntersectsWith(Properties.Settings.Default.WindowPosition))) { StartPosition = FormStartPosition.Manual; DesktopBounds = Properties.Settings.Default.WindowPosition; WindowState = FormWindowState.Normal; } } private void MyForm_FormClosing(object sender, FormClosingEventArgs e) { Properties.Settings.Default.IsMaximized = WindowState == FormWindowState.Maximized; Properties.Settings.Default.WindowPosition = DesktopBounds; Properties.Settings.Default.Save(); }
用户设置:
<userSettings> <WindowsFormsApplication2.Properties.Settings> <setting name="WindowPosition" serializeAs="String"> <value>0, 0, -1, -1</value> </setting> <setting name="IsMaximized" serializeAs="String"> <value>False</value> </setting> </WindowsFormsApplication2.Properties.Settings> </userSettings>
注意:WindowsPosition是故意错误的,所以在第一次启动时应用程序将使用默认位置。
Matt – 将“WindowState”保存为用户设置,在“设置”对话框的“types”下拉列表中,滚动到底部,然后select“浏览”。
在“selecttypes”对话框中,展开System.Windows.Forms,然后select“FormWindowState”作为types。
(对不起,我没有看到一个button,允许我评论评论…)
你必须手动保存信息的地方。 我build议这样做的应用程序设置,将其存储在用户特定的孤立存储。
一旦你加载,阅读设置,然后resize/移动您的表单。
如果你有超过1个表格,你可以使用这样的东西…
添加这个部分全部forms为load void
var AbbA = Program.LoadFormLocationAndSize(this); this.Location = new Point(AbbA[0], AbbA[1]); this.Size = new Size(AbbA[2], AbbA[3]); this.FormClosing += new FormClosingEventHandler(Program.SaveFormLocationAndSize);
保存表单的位置和大小到app.config xml
public static void SaveFormLocationAndSize(object sender, FormClosingEventArgs e) { Form xForm = sender as Form; Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); if (ConfigurationManager.AppSettings.AllKeys.Contains(xForm.Name)) config.AppSettings.Settings[xForm.Name].Value = String.Format("{0};{1};{2};{3}", xForm.Location.X, xForm.Location.Y, xForm.Size.Width, xForm.Size.Height); else config.AppSettings.Settings.Add(xForm.Name, String.Format("{0};{1};{2};{3}", xForm.Location.X, xForm.Location.Y, xForm.Size.Width, xForm.Size.Height)); config.Save(ConfigurationSaveMode.Full); }
从app.config xml加载表单的位置和大小
public static int[] LoadFormLocationAndSize(Form xForm) { int[] LocationAndSize = new int[] { xForm.Location.X, xForm.Location.Y, xForm.Size.Width, xForm.Size.Height }; //---// try { Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); var AbbA = config.AppSettings.Settings[xForm.Name].Value.Split(';'); //---// LocationAndSize[0] = Convert.ToInt32(AbbA.GetValue(0)); LocationAndSize[1] = Convert.ToInt32(AbbA.GetValue(1)); LocationAndSize[2] = Convert.ToInt32(AbbA.GetValue(2)); LocationAndSize[3] = Convert.ToInt32(AbbA.GetValue(3)); } catch (Exception ex) { MessageBox.Show(ex.Message); } //---// return LocationAndSize; }
如果你使用神话般的开源库–Jot ,你可以忘记繁琐的.settings文件,只是这样做:
public MainWindow() { InitializeComponent(); _stateTracker.Configure(this) .IdentifyAs("MyMainWindow") .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState)) .RegisterPersistTrigger(nameof(Closed)) .Apply(); }
还有一个Nuget包,你可以configuration几乎所有关于数据存储的方式/时间/地点。
免责声明:我是作者,但图书馆是完全开源的(根据MIT许可证)。
我的答案是从ChrisF♦的答案改编的 ,但是我已经修复了一个我不喜欢的东西 – 如果窗口在closures的时候被最小化,那么在下一次开始的时候会显示最小化。
我的代码通过记住窗口在最小化时是最大化还是正常来处理这种情况,并相应地设置持久状态。
不幸的是,Winforms不直接公开这些信息,所以我需要重写WndProc并自己存储。 请参阅检查当前最小化窗口在最小化时是处于最大化还是正常状态
partial class Form1 : Form { protected override void WndProc(ref Message m) { if (m.Msg == WM_SYSCOMMAND) { int wparam = m.WParam.ToInt32() & 0xfff0; if (wparam == SC_MAXIMIZE) LastWindowState = FormWindowState.Maximized; else if (wparam == SC_RESTORE) LastWindowState = FormWindowState.Normal; } base.WndProc(ref m); } private const int WM_SYSCOMMAND = 0x0112; private const int SC_MAXIMIZE = 0xf030; private const int SC_RESTORE = 0xf120; private FormWindowState LastWindowState; private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (WindowState == FormWindowState.Normal) { Properties.Settings.Default.WindowLocation = Location; Properties.Settings.Default.WindowSize = Size; } else { Properties.Settings.Default.WindowLocation = RestoreBounds.Location; Properties.Settings.Default.WindowSize = RestoreBounds.Size; } if (WindowState == FormWindowState.Minimized) { Properties.Settings.Default.WindowState = LastWindowState; } else { Properties.Settings.Default.WindowState = WindowState; } Properties.Settings.Default.Save(); } private void Form1_Load(object sender, EventArgs e) { if (Properties.Settings.Default.WindowSize != new Size(0, 0)) { Location = Properties.Settings.Default.WindowLocation; Size = Properties.Settings.Default.WindowSize; WindowState = Properties.Settings.Default.WindowState; } }
我尝试了几种不同的方法。 这是什么结束了为我工作。 (在这种情况下 – 首次启动时,默认值还没有被保存,所以表单将使用devise器中设置的值)
-
将设置添加到项目中(手动 – 不要依赖Visual Studio):
-
将以下代码添加到您的表单中:
private void Form1_Load(object sender, EventArgs e) { this.RestoreWindowPosition(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.SaveWindowPosition(); } private void RestoreWindowPosition() { if (Settings.Default.HasSetDefaults) { this.WindowState = Settings.Default.WindowState; this.Location = Settings.Default.Location; this.Size = Settings.Default.Size; } } private void SaveWindowPosition() { Settings.Default.WindowState = this.WindowState; if (this.WindowState == FormWindowState.Normal) { Settings.Default.Location = this.Location; Settings.Default.Size = this.Size; } else { Settings.Default.Location = this.RestoreBounds.Location; Settings.Default.Size = this.RestoreBounds.Size; } Settings.Default.HasSetDefaults = true; Settings.Default.Save(); }