窗体布局持久化, 包括其所有子控件






2.24/5 (8投票s)
2005年1月19日
2分钟阅读

29144

507
本文介绍了如何使用一个微小的控件来确保你的表单的布局持久性。
引言
本文介绍了如何通过将 Windows 窗体的句柄传递给布局持久性控件,让其自动安排其布局。
注意:基本思想来自文章:.NET 应用程序的窗口状态和外观的持久性(Alexander Fedorenko)。我采用了他的代码,该代码主要关注在表单组件集合中找到的顶级控件。现在大量使用递归,该控件能够重新排列表单中的所有控件,即使它们是子控件的子控件...
如何使用
只需引用程序集,并在你的主窗体中使用它,如下所示。
using Dau.UI.Forms;
然后,创建一个控件的单个实例,并传递你的主窗体的句柄和注册表键名,该控件将在那里(重新)存储其设置!
private FormPersistence formPersistence;
public MainForm()
{
InitializeComponent();
formPersistence = new FormPersistence(this,"Dau\\Test\\Settings");
formPersistence.IsSavingOnMove = false;
}
最后一行告诉控件在调整窗体大小时不要保存设置。这将大大提高你应用程序的绘图性能。对于位于你表单上的少量控件,你不会注意到差异。
工作原理
由于我从另一篇文章中获得了这个想法,所以我不会在这里描述它的线索,但我会简要地解释我是如何改进它来布局所有子控件的。
protected void SaveControlsRecursively ( Control.ControlCollection p_controls,
string p_sParentControlConstantsPath)
{
string sCurrentPath;
foreach(Control control in p_controls)
{
//update control name for each cycle call
sCurrentPath = p_sParentControlConstantsPath +"." + control.Name;
//write this controls values
SaveControl(control,sCurrentPath );
//recursuve call to child controls
if ( m_Recursive )
SaveControlsRecursively ( control.Controls , sCurrentPath );
}
}
正如你在代码片段中看到的,如果 recursive 为 true
,我会在自身中调用相同的函数。所有控件容器都具有属性 `Controls`,如果你调用它,它会使循环遍历控件及其所有子控件变得非常容易。终止条件在这里有点隐藏,但你的代码不会无休止地循环,因为递归调用发生在控件循环的末尾。如果一个控件没有更多的子控件,那么该函数将退出。
在函数 `RestoreControl` 中,完成了最棘手的事情
if ( control.Dock != DockStyle.None )
control.Bounds = profile.Read(p_sCurrentName + "." + Constants.Bounds );
该函数仅在控件的 `DockStyle` 设置为某个 dockstyle 时才应用 `Bounds` 值。这非常重要,因为你不能处理使用锚点(无论如何都自我定位)的控件的布局。
基本上就是这样。不要忘记调用持久性对象的 dispose 方法,因为它会保持其注册表键处于打开状态,只要对象存在,以确保最佳性能!