如何在程序运行之间保存/恢复表单和控件?

时间:2010-07-07 02:59:31

标签: vb.net winforms visual-studio-2008

我有一个复杂的表单,允许用户配置我的应用程序。

保存表单状态的最佳方法是什么?程序下次运行时重新加载。

我指的是他在列表框中输入的文字,所选的组合/列表/收音机项目,复选框是否被颊等等

7 个答案:

答案 0 :(得分:3)

很多人在这里告诉我什么时候保存,但没有多少人告诉我如何......

最后我选择了WritePrivateProfileString()

答案 1 :(得分:1)

您可以选择在哪里保存输入的设置 - 在配置文件中,或在注册表中,可能是数据库(甚至可能是“云”,但我不会去那里)。

您应该让用户在保存设置之前执行特定操作(例如单击应用按钮) - 您不应该只在用户关闭表单时保存设置,如这最终不是很好的用户体验。

如何保存设置完全取决于您 - 您可以将它们保存为直接的名称/值对样式配置文件,您可能希望在配置文件中使用XML,或者将它们保存为键和值注册表中的已知位置(或者您可以将名称/值对保存到数据库表中)。

下次运行应用程序时,其中一个启动任务可能是检查设置的已知位置(无论是注册表还是配置文件),然后将它们加载到设置类中。确保每个设置都有逻辑默认值,以防它从未设置过,或者由于某种原因你无法读回来。然后可以将设置类传入每个表单,以便应用任何设置相关的,或者它可以是一个静态类(全局可见的单实例类),以便它可以从应用程序的任何地方读取。

编辑:在阅读了对其他答案的评论后,这是另一个选项,略高一些。使用前面提到的设置类,但也使用绑定 - 您可以将设置对象直接绑定到表单,因此输入的任何值都将直接更新到设置对象中,而无需编写代码来执行此操作(前提是您使用了两个方式绑定)。可以通过将设置对象序列化到文件(或数据库)来实现“流式传输”,我建议您查看XmlSerializer

答案 2 :(得分:1)

序列化表单。

实现ISerializable,并在serializable构造函数和GetObject()方法中加载/保存您的字段。

OnClosing序列化表单中。

    /// 
    /// try to obtain the las serialized main form with old data
    MainForm mainForm = DeserializeMainForm("mainForm.data");
    ///
    /// if any old data found, create a new(empty) main form
    if (mainForm == null) mainForm = new MainForm();

    static MainForm DeserializeMainForm(string filePath)
    {
        MainForm mf = null;
        FileStream fileStream = null;
        try
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            fileStream = new FileStream(filePath, FileMode.Open);
            mf = (MainForm)binaryFormatter.Deserialize(fileStream);
        }
        catch { }
        finally
        {
            if (fileStream != null)
            {
                fileStream.Close();
            }
        }

        return mf;
    }

的MainForm:

[Serializable]
public partial class MainForm : Form, ISerializable
{
        protected MainForm(SerializationInfo info, StreamingContext context)
        : this()
    {
        if (info == null)
            throw new System.ArgumentNullException("info");

        this.tbxServerIp.Text = info.GetString("server ip");
        this.tbxServerPort.Text = info.GetString("server port");
        this.tbxEventFilter.Text = info.GetString("event filter");
        this.tbxWallId.Text = info.GetString("wallId");

        foreach (Control control in this.Controls)
        {
            if (control is EventSender)
            {
                EventSender eventSender = (control as EventSender);
                eventSender.LoadFromSerializationInfo(info);
            }
        }   
    }

    private void SerializeThis()
    {
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        FileStream fileStream = new FileStream("mainForm.data", FileMode.Create);
        try
        {
            binaryFormatter.Serialize(fileStream, this);
        }
        catch
        {
            throw;
        }
        finally
        {
            fileStream.Close();
        }
    }

    protected override void OnClosing(CancelEventArgs e)
    {
        SerializeThis();
        base.OnClosing(e);
    }
}

答案 3 :(得分:0)

Private Sub frm_Closing (sender as Object, e as CancelEventArgs) Handles MyBase.Closing

   ' save all the values you want'

End Sub

Private Sub frm_Load(sender as Object, e as EventArgs) Handles MyBase.Load

   If SaveSettingsExist Then
      ' restore all the values you want'
   End If

End Sub

答案 4 :(得分:0)

我实际上有一些我用这样的通用例程来保存表单大小/位置和ListView列设置。所以我有类似......

Private Sub frm_Closing (sender as Object, e as CancelEventArgs) Handles MyBase.Closing

   SaveFormPos(Me)
   SaveListview(Me, lvuInvoices)

End Sub

Private Sub frm_Load(sender as Object, e as EventArgs) Handles MyBase.Load

   RestoreFormPos(Me)
   RestoreListview(Me, lvuInvoices)

End Sub

Me参数(对于Listview例程)用于为要保存到注册表的值创建密钥。你面前有各种各样的选择。您可以将此功能放入所有表单的基类中,创建SaveState类,或者只是将例程粘贴到模块中。您可以将此数据保存到注册表,数据库和文本文件中。您可以使用一个通用例程来遍历Controls集合,查找TextBox,Checkbox等等。

但是,一旦你创建了一组有用的保存例程,你就可以在你想要的任何后续表格上使用它们,所以你只需要做一次艰苦的工作。

答案 5 :(得分:0)

我也同意在创建表单/关闭应用程序时调用一组LoadSettings/SaveSettings函数。

作为应用程序设置的商店位置,我建议使用Isolated Storage

另外,根据您在表单上使用的控件,您可以选择以XML格式保存其状态,然后在下次还原时使用。 例如,Infragistics控件提供了这种可能性(例如UltraDockManagerUltraToolbarManager具有SaveAsXml/LoadFromXml对函数。)

答案 6 :(得分:-1)

您可以以隐藏的形式以隐藏的textbox以某种方式保存所有内容。 当用户单击apply按钮时,自动打开文本文件并使程序逐行读取。

示例:

  • 第1行可以是图像的位置
  • 第2行可以是文本框的文本
  • 第3行可以是程序用来确定是否为a的单词或数字 复选框为true或false