如何在 MDI 表单仪表板上保存配置 [英] How to save the configuration on a MDI Forms Dashboard

查看:26
本文介绍了如何在 MDI 表单仪表板上保存配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating a dashboard (in VB.NET) with multiple modules. Every module is a different form with different functions and settings and the user can create how many and how much of these forms he want. My idea is to make possible to save the general configuration of the Dashboard (example: forms opened, position of these etc.) to be able to recall it when the main form is closed and re-opened and obtain the same situation or change between different settings (different user can load it's own custom preset).

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

I've tried to serialize the list of forms that are opened but serializing MDI child Forms causes trouble.

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

All the Forms are ok and works with its own settings. I need only the way to implement this kind of "global settings save".

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

How can I do this in the most elegant way? (it's ok also a rough idea than I can try getting in deep on my own)

谢谢!

推荐答案

要保存所有打开的 MDIChild Windows 的位置,可以枚举 MDIParent 的 MdiClient 容器(实际上是 MDI 子窗口的父容器).
这将为您提供显示这些 Windows 的正确顺序.
Application.OpenForms 合集获胜't,它只是枚举打开的表单.

To save the position of all opened MDIChild Windows, you can enumerate the collection of Controls of the MDIParent's MdiClient container (the Container that actually parents the MDI Child Windows).
This will give you the correct order in which these Windows are shown.
The Application.OpenForms collection won't, it just enumerates the opened Forms.

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

You can use the Form.Name as reference and save its Bounds Rectangle.
Here, I'm using the RectangleConverter class to serialize the Forms' Bounds.

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

► Here, I'm serializing just the Form Name and its Bounds. You can of course serialize whatever other properties / values you need.
In that case, you can build a class structure that stores the information and serialize it using a Json or XML Serializer (I suggest the former. IMO, avoid BinaryFormatter).

要同时保存 MDIParent 的边界,请将其最后添加到列表中,因为当您读回表单列表时,您必须反转表单的创建顺序(最后创建的在顶部).

To also save the Bounds of the MDIParent, add it last to the list, since when you read back the list of Forms, you have to invert the order in which the Forms are created (the last created goes on top).

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

To recreate the Forms, you can use Activator.CreateInstance, passing the Type of the Form to create.

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

The file that stores this information is saved in Application.CommonAppDataPath:

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

它指向安装系统的驱动器的 ProgramData 文件夹.您的应用始终在此处拥有写入权限.

It points to the ProgramData folder of the drive where the System is installed. Your app always has write permissions here.

当 MDI 应用程序即将关闭时(Form.FormClosing 事件处理程序),SaveWindowsOrder() 方法被调用.它将存储所有打开的窗口的当前 Order 和 Bounds,包括 MDIParent.

When the MDI Application is about to close (Form.FormClosing event handler), the SaveWindowsOrder() method is called. It will store the current Order and Bounds of all opened windows, MDIParent included.

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

When the MDI Parent is about to be shown (Form.Shown event handler), the LoadWindowsOrder() is called, to restore the previous layout.

添加这些导入:

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

公共方法.添加到表单、模块或添加 Shared 并使用专用帮助器类.

Public methods. Add to the Form, to Module or add Shared and use a dedicated helper 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

这篇关于如何在 MDI 表单仪表板上保存配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆