如何在 MDI Forms Dashboard 上保存配置

How to save the configuration on a MDI Forms Dashboard

我正在创建一个包含多个模块的仪表板(在 VB.NET 中)。每个模块都是具有不同功能和设置的不同形式,用户可以创建他想要的这些形式的数量和数量。我的想法是可以保存仪表板的一般配置(例如:打开的表格,这些的位置等)以便能够在主窗体关闭和重新打开时调用它并获得相同的情况或之间的变化不同的设置(不同的用户可以加载自己的自定义预设)。

我尝试序列化已打开的表单列表,但序列化 MDI 子表单会导致问题。

所有表单都可以,并且可以使用自己的设置。我只需要实现这种“全局设置保存”的方法即可。

我怎样才能以最优雅的方式做到这一点? (这也是一个粗略的想法,我可以尝试自己深入研究)

谢谢!

要保存所有打开的 MDIChild Windows 的位置,您可以枚举 MDIParent 的 MdiClient 容器的控件集合(实际上是 MDI Child Windows 父级的容器) .
这将为您提供显示这些 Windows 的正确顺序。
Application.OpenForms 集合不会,它只是枚举打开的表单。

您可以使用 Form.Name 作为参考并保存其 Bounds 矩形。
在这里,我使用 RectangleConverter class 来序列化表单的边界。

▶ 在这里,我只是 序列化 表单名称及其边界。您当然可以序列化您需要的任何其他属性/值。
在这种情况下,您可以构建一个 class 结构来存储信息并使用 Json 或 XML 序列化程序对其进行序列化(我建议前者。IMO,避免使用 BinaryFormatter) .

为了同时保存 MDIParent 的边界,请将其最后添加到列表中,因为当您读回表单列表时,您必须颠倒创建表单的顺序(最后创建的在最上面) ).

要重新创建表单,您可以使用 Activator.CreateInstance,传递要创建的表单类型。

存储此信息的文件保存在Application.CommonAppDataPath:

Path.Combine(Application.CommonAppDataPath, "FormsLayout.txt")

它指向安装系统的驱动器的 ProgramData 文件夹 - 专用于调用应用程序。您的应用在此处始终具有写入权限。

当 MDI 应用程序即将关闭时(Form.FormClosing 事件处理程序),调用 SaveWindowsOrder() 方法。它将存储所有打开的当前顺序和边界 windows,包括 MDIParent。

当 MDI Parent 即将显示时(Form.Shown 事件处理程序),LoadWindowsOrder() 被调用,以恢复之前的布局。

添加这些 Imports:

Imports System.Drawing ' If not already defined in the Project's References
Imports System.IO
Imports System.Linq    ' If not already defined in the Project's References
Imports System.Reflection

Public 方法
添加到表单、模块,或者,如果您愿意,添加 Shared 并使用专用助手 class.

Public Sub SaveWindowsOrder(filePath As String, mdiPparent As Form)
    Dim formsOrder As New List(Of String)
    Dim mClient = mdiPparent.Controls.OfType(Of MdiClient).First()

    For Each f As Form In mClient.Controls.OfType(Of Form).ToList()
        Dim sRect = New RectangleConverter().ConvertToString(f.Bounds)
        formsOrder.Add($"{f.Name};{sRect}")
    Next
    formsOrder.Add($"{mdiPparent.Name};{New RectangleConverter().ConvertToString(mdiPparent.Bounds)}")
    File.WriteAllLines(filePath, formsOrder)
End Sub

Public Sub LoadWindowsOrder(filePath As String, parent As Form)
    If Not File.Exists(filePath) Then Return

    Dim orderList = File.ReadAllLines(filePath).Reverse().ToArray()
    Dim appNameSpace = Assembly.GetExecutingAssembly().GetName().Name

    Dim parentData = orderList(0).Split(";"c)
    parent.Bounds = CType(New RectangleConverter().ConvertFromString(parentData(1)), Rectangle)

    For Each formOrder As String In orderList.Skip(1).ToArray()
        Dim params = formOrder.Split(";"c)
        Dim formName As String = params(0)
        Dim formBounds = CType(New RectangleConverter().ConvertFromString(params(1)), Rectangle)

        Dim form = CType(Activator.CreateInstance(Type.GetType($"{appNameSpace}.{formName}")), Form)
        form.MdiParent = parent
        form.Show()
        form.Bounds = formBounds
    Next
End Sub

添加到 MDIParent 表格:

Private Sub MDIParent1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    Dim layoutFile = Path.Combine(Application.CommonAppDataPath, "FormsLayout.txt")
    SaveWindowsOrder(layoutFile, Me)
End Sub

Private Sub MDIParent1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    Dim layoutFile = Path.Combine(Application.CommonAppDataPath, "FormsLayout.txt")
    LoadWindowsOrder(layoutFile, Me)
End Sub