保存对表单控件所做的更改? [复制]

Posted

技术标签:

【中文标题】保存对表单控件所做的更改? [复制]【英文标题】:Saving changes made to controls on form? [duplicate] 【发布时间】:2015-07-03 15:29:02 【问题描述】:

问题

如何保存“设置”,以便在关闭应用程序后再次使用?

当我说设置时,我的意思是表单上控件的不同属性。

什么是最简单最合适的方法?我读过你可以保存到系统注册表或xml文件吗?

背景

我有一个表单,它在表中创建一行,该行根据设置或更改的控件而变化。

我希望能够保存不同的配置并将它们显示在组合框中以供重复使用。

示例

    最终用户填写所有文本框并勾选复选框。 然后他们点击添加到收藏夹 他们添加一个喜欢的名字并保存 然后保存在收藏夹组合框中永久可见。

我的表格


【问题讨论】:

保存在哪里?文件系统? 我在 Google 中输入了“c# save settings”并得到了这个:How To: Write User Settings at Run Time with C# 这是一篇很好的 MSDN 文章msdn.microsoft.com/en-us/library/aa730869%28v=vs.80%29.aspx 保存信息到列表,3行序列化;再读 3 遍 我不同意你的理由。编写 MSDN 教程是为了使该语言的新手更容易接受官方文档; 正是您应该阅读的内容。如果您在阅读这些教程时遇到问题,那将是公平的游戏,但直截了当地说您不会费心阅读它们并不是程序员应有的态度。此外,你甚至检查过这个网站吗?已经有一些问题涉及您的具体问题,例如 this 或 this。 【参考方案1】:

有很多方法可以做到这一点。但是在所有这些选项中,您需要将用户选择存储在某处。您可以将其存储在

    数据库表,将设置与唯一的用户 ID 相关联,例如 LoginID 首选项 XML 文件:Refer this 作为项目中的设置:Refer this 作为注册表项:Refer this INI 文件

你可能想看看Persisting Application Settings in the .NET Framework

【讨论】:

注意:我特别在我的回答中留下了注册表项。并不是说它不是一个选择,只是考虑一下它不是一个好主意的所有原因:***.com/questions/2600161/… @maplemale 完全同意...只是想把所有选项都放在桌子上...【参考方案2】:

保存数据的一种方法是将其写入注册表,在 HKCU 节点下。这样,即使应用程序在同一台机器上,应用程序的不同用户也将拥有自己的设置。它还使文件系统更整洁,并且不需要数据库。但缺点是收藏夹只存在于机器上,不会随用户跨设备漫游。

实现这一点的一种方法是将表单设置包装在一个知道如何从注册表保存和加载值的类中。这与注册表帮助程序类一起,可以很容易地将“收藏夹”功能添加到您的表单中。

例如,您可以首先创建一个 Registry 帮助程序类,它将读取和写入 HKCU 节点的设置(因此这些设置特定于登录用户):

public class RegHelper

    private static readonly RegistryKey Root = Registry.CurrentUser
        .CreateSubKey(@"Software\CompanyName\ApplicationName");

    private readonly RegistryKey _thisKey = Root;

    public RegHelper()  

    public RegHelper(string favoriteKey)
    
        _thisKey = Root.CreateSubKey(favoriteKey);
    

    public List<string> GetSubKeys()
    
        return _thisKey.GetSubKeyNames().ToList();
    

    public void SetProperty(string propertyName, string value)
    
        _thisKey.SetValue(propertyName, value, RegistryValueKind.String);
    

    public void SetProperty(string propertyName, bool value)
    
        SetProperty(propertyName, value.ToString());
    

    public string GetProperty(string propertyName)
    
        return GetProperty(propertyName, string.Empty);
    

    public string GetProperty(string propertyName, string defaultValue)
    
        return _thisKey.GetValue(propertyName, defaultValue).ToString();
    

    public bool GetPropertyAsBool(string propertyName)
    
        return bool.Parse(GetProperty(propertyName, default(bool).ToString()));
    

然后,您可以将表单的字段包装到一个类中,该类不仅具有与表单字段匹配的属性,而且还具有将值保存到注册表的方法和一些静态方法来加载所有收藏夹或特定命名的最喜欢的。例如:

public class Favorite

    public string Name  get; private set; 
    public string Notes  get; set; 
    public bool NotesFromPlanner  get; set; 
    public string Project  get; set; 
    public string DbLocation  get; set; 
    public string AssesmentToolVersion  get; set; 
    public string ProjectCodes  get; set; 
    public bool StraightToNew  get; set; 

    public Favorite(string name)
    
        this.Name = name;
    

    public void Save()
    
        var reg = new RegHelper(this.Name);
        reg.SetProperty("Name", Name);
        reg.SetProperty("Notes", Notes);
        reg.SetProperty("NotesFromPlanner", NotesFromPlanner);
        reg.SetProperty("Project", Project);
        reg.SetProperty("DbLocation", DbLocation);
        reg.SetProperty("AssesmentToolVersion", AssesmentToolVersion);
        reg.SetProperty("ProjectCodes", ProjectCodes);
        reg.SetProperty("StraightToNew", StraightToNew);
    

    public static Favorite GetFavorite(string favoriteName)
    
        var reg = new RegHelper(favoriteName);
        return new Favorite(favoriteName)
        
            Notes = reg.GetProperty("Notes"),
            NotesFromPlanner = reg.GetPropertyAsBool("NotesFromPlanner"),
            Project = reg.GetProperty("Project"),
            DbLocation = reg.GetProperty("DbLocation"),
            AssesmentToolVersion = reg.GetProperty("AssesmentToolVersion"),
            ProjectCodes = reg.GetProperty("ProjectCodes"),
            StraightToNew = reg.GetPropertyAsBool("StraightToNew"),
        ;
    

    public static List<Favorite> GetFavorites()
    
        return new RegHelper().GetSubKeys().Select(GetFavorite).ToList();
    

    public override string ToString()
    
        return this.Name;
    

然后,您可以使用收藏夹类来填充您的收藏夹下拉:

private void Form1_Load(object sender, EventArgs e)

    // Get all saved favorites and load them up in the combo box
    foreach (var favorite in Favorite.GetFavorites())
    
        cboFavorites.Items.Add(favorite);
    

现在,当从组合框中选择最喜欢的内容时,我们想用详细信息填充我们的表单:

private void cboFavorites_SelectedIndexChanged(object sender, EventArgs e)

    var favorite = (Favorite) cboFavorites.SelectedItem;

    txtNotes.Text = favorite.Notes;
    txtAssetToolVersion.Text = favorite.AssesmentToolVersion;
    txtDbLocation.Text = favorite.DbLocation;
    chkNotesFromPlanner.Checked = favorite.NotesFromPlanner;
    txtProjectCodes.Text = favorite.ProjectCodes;
    cboProjects.Text = favorite.Project;
    chkStraightToNew.Checked = favorite.StraightToNew;

当有人点击“保存收藏”时,我们希望将收藏的详细信息添加(或更新)到注册表中:

private void btnAddFavorite_Click(object sender, EventArgs e)

    string favoriteName = cboFavorites.Text;

    if (string.IsNullOrEmpty(favoriteName))
    
        MessageBox.Show("Please type a name for the favorite in the Favorites box.");
        return;
    

    var favorite = new Favorite(favoriteName)
    
        Notes = txtNotes.Text,
        AssesmentToolVersion = txtAssetToolVersion.Text,
        DbLocation = txtDbLocation.Text,
        NotesFromPlanner = chkNotesFromPlanner.Checked,
        ProjectCodes = txtProjectCodes.Text,
        Project = cboProjects.Text,
        StraightToNew = chkStraightToNew.Checked
    ;

    favorite.Save();

    // When saving a favorite, add it to the combo box
    // (remove the old one first if it already existed)
    var existingFav = cboFavorites.Items.Cast<Favorite>()
        .FirstOrDefault(fav => fav.Name == favoriteName);
    if (existingFav != null)
    
        cboFavorites.Items.Remove(existingFav);
    

    cboFavorites.Items.Add(favorite);
    cboFavorites.Text = favoriteName;

这应该足以让你开始,如果你想去注册路线。

【讨论】:

您只需使用 AppData\Roaming 即可实现您列出的所有好处并避免限制。这是专门为程序转储其设置而设计的,普通用户并不关心,因为他们默认看不到它。 如果它使用 xml 或所有用户都可以使用相同设置的方式,这将是完美的。使用 reg 对我的项目有极大的限制。【参考方案3】:

这取决于您的应用程序及其用途及其架构。

有多种选择:

    您可以将其保存在数据库中。 当有很多设置时,这个选项很好,在多用户平台中特别好。如果这是一个客户端服务器应用程序,由于这个原因,这也可能是更可取的。如果您想保持简单,并且不希望用户设置变得复杂/有很多,这可能不是最佳选择。

    您可以将其保存在平面文件中。此选项与第一个选项类似,但在您的应用程序更加独立和/或您在服务器上设置这些设置没有任何其他好处的情况下可能会更好。

    您可以将它们存储在您的应用程序设置中。关于如何做到这一点,这里有一个很好的答案:https://msdn.microsoft.com/en-us/library/0zszyc6e%28v=vs.110%29.aspx

要考虑的另一件事是您希望如何加载这些设置。对于 Windows 窗体开发,拥有定义布局并绑定到这些类的类可能很有用。因此,您可能希望将这些数据存储在 XML 中,该 XML 可以轻松地直接序列化为定义表单外观的类。您将能够将该 XML 存储在真正的任何地方:本地或数据库中的服务器上。

【讨论】:

以上是关于保存对表单控件所做的更改? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在visual studio 2008中运行时,表单不显示更改

无论控件如何,在表单上的任何控件更新后有啥方法可以触发事件?

动态创建DTPicker控件

更改 .NET 中单个表单控件的不透明度

如何保存对 Python 列表所做的更改,以便在重新运行脚本后更新? [复制]

在 Access 表单上将控件分组在一起