65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.24/5 (8投票s)

2005年1月19日

2分钟阅读

viewsIcon

29144

downloadIcon

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 方法,因为它会保持其注册表键处于打开状态,只要对象存在,以确保最佳性能!

© . All rights reserved.