未保存应用程序设置

本文关键字:设置 应用程序 保存 | 更新日期: 2023-09-27 18:06:47

我想在应用程序设置中保存一个StringDictionary,以便在应用程序启动时用保存的值填充我的列表框lbc_lastCustomersVisited

这是我的应用程序设置(XML格式):

<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Wibe_EFI.Properties" GeneratedClassName="Settings">
    <Profiles />
    <Settings>
        <Setting Name="ApplicationSkinName" Type="System.String" Scope="User">
            <Value Profile="(Default)" />
        </Setting>
        <Setting Name="LastTimeWibeDataObtained" Type="System.String" Scope="User">
            <Value Profile="(Default)" />
        </Setting>
        <Setting Name="LastVisitedCustomer" Type="System.Collections.Specialized.StringDictionary" Scope="User">
            <Value Profile="(Default)" />
        </Setting>
  </Settings>


在我的形式中,我有一个StringDictionary局部变量:

public partial class MainForm : XtraForm
{
    private StringDictionary lastVisitedCustomers = new StringDictionary();
    [...]
}


以下是我如何填充StringDictionary局部变量:

private void btn_selectCustomer_Click(object sender, EventArgs e)
{
    DataRowView selectedRow = GetCustomersGridSelectedRow();
    lastVisitedCustomers.Add(GetCustomerID(selectedRow), String.Format("{0} - {1}", GetCustomerName(selectedRow), GetCustomerCity(selectedRow)));
}

( StringDictionary已成功填充)

FormClosing,我保存设置:

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
        Settings.Default["ApplicationSkinName"] = UserLookAndFeel.Default.SkinName;
        Settings.Default.LastVisitedCustomer = lastVisitedCustomers;
        Settings.Default.Save();
}

成功保存设置ApplicationSkinName,但未保存设置lastVisitedCustomer StringDictionary。因为当我在应用启动时加载设置时,Settings.Default.LastVisitedCustomernull


下面是我如何加载关于应用程序皮肤的设置(它有效):

public MainForm()
{
        InitializeComponent();
        InitSkinGallery();
        UserLookAndFeel.Default.SkinName = Settings.Default["ApplicationSkinName"].ToString();
}

但是我不能在这里加载我的StringDictionnary,因为NullReferenceException
所以我在这里加载:

private void MainForm_Load(object sender, EventArgs e)
{
    _mySqlCeEngine = new MySqlCeEngine(this);
    ShowHomePanel();
    LoadLastVisitedCustomers();
}
private void LoadLastVisitedCustomers()
{
    if (Settings.Default.LastVisitedCustomer.Count > 0)
    {
        lastVisitedCustomers = Settings.Default.LastVisitedCustomer;
    }
    lbc_lastCustomersVisited.DataSource = new BindingSource(lastVisitedCustomers, null);
    lbc_lastCustomersVisited.DisplayMember = "Value";
    lbc_lastCustomersVisited.ValueMember = "Key";
}

但是在这个时刻,Settings.Default.LastVisitedCustomer是空的,我不明白为什么。我尝试了一些事情,如不使用局部变量和直接从Settings.Default.LastVisitedCustomer读/写,但我得到了同样的问题。

谢谢,

悍妇。

EDIT:添加完整的Settings.settings文件(XML视图)

未保存应用程序设置

如果你想尝试,我试着通过创建一个新的表单应用程序来产生错误:

namespace WindowsFormsApplication2
{
  public partial class Form1 : Form
  {
    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        test.Text = (string)Settings.Default["lastCustomers"];
    }
    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        Settings.Default["lastCustomers"] = test.Text;
        Settings.Default.Save();
    }
  }
}

在这个例子中,代码工作了。创建一个新的表单应用程序,并添加一个名称为test的文本框。每次您关闭程序并重新启动它时,您在文本框中写入的字符串将被保存并重新加载到test.Text中。

在你的例子中,你的构造函数应该是这样的:(可能的解决方案)

public MainForm()
{
    InitializeComponent();
    InitSkinGallery();
    UserLookAndFeel.Default.SkinName = Settings.Default["ApplicationSkinName"].ToString();
    lastVisitedCustomers = (StringDictionary)Settings.Default["LastVisitedCustomer"];
}

之后保存设置和加载时一样:

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    Settings.Default["ApplicationSkinName"] = UserLookAndFeel.Default.SkinName;
    Settings.Default["LastVisitedCustomer"] = lastVisitedCustomers;
    Settings.Default.Save();
}

这应该能解决你的问题!

编辑哦,当然,你的加载函数看起来不一样了:

private void MainForm_Load(object sender, EventArgs e)
{
    _mySqlCeEngine = new MySqlCeEngine(this);
    ShowHomePanel();
    LoadLastVisitedCustomers();
}

private void LoadLastVisitedCustomers()
{
    lbc_lastCustomersVisited.DataSource = new BindingSource(lastVisitedCustomers, null);
    lbc_lastCustomersVisited.DisplayMember = "Value";
    lbc_lastCustomersVisited.ValueMember = "Key";
}

我找不到在应用程序设置中存储Dictionary的任何解决方案,所以我决定处理string并拆分它:

public partial class MainForm : XtraForm
{
    private Dictionary<string, string> lastVisitedCustomers;
    public MainForm()
    {
        InitializeComponent();
        InitSkinGallery();
        UserLookAndFeel.Default.SkinName = Settings.Default["ApplicationSkinName"].ToString();
        lastVisitedCustomers = StringToDictionary(Settings.Default["LastVisitedCustomer"].ToString());
    }
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        Settings.Default["ApplicationSkinName"] = UserLookAndFeel.Default.SkinName;
        Settings.Default["LastVisitedCustomer"] = DictionaryToString(lastVisitedCustomers);
        Settings.Default.Save();
    }
    #region Dictionary management
    private string DictionaryToString(Dictionary<string, string> dic)
    {
        if (dic.Count == 0)
        {
            return string.Empty;
        }
        else
        {
            string dicString = string.Empty;
            int i = 0;
            foreach (KeyValuePair<string, string> entry in dic)
            {
                if (i == 0)
                {
                    dicString = String.Format("{0} ## {1}", entry.Key, entry.Value);
                    i++;
                }
                else
                {
                    dicString += String.Format(" -- {0} ## {1}", entry.Key, entry.Value);
                }
            }
            return dicString;
        }
    }
    private Dictionary<string, string> StringToDictionary(string str)
    {
        Dictionary<string, string> dic = new Dictionary<string,string>();
        if (String.IsNullOrEmpty(str))
        {
            return dic;
        }
        else
        {
            string[] entries = Regex.Split(str, " -- ");
            foreach (string entry in entries)
            {
                string[] kvp = Regex.Split(entry, " ## ");
                dic.Add(kvp[0], kvp[1]);
            }
            return dic;
        }
    }
}
    #endregion

现在,它工作。
我希望它能帮助到和我一样的人。

注意:您可能必须修改我的字典方法,以便处理每个例外情况。但我觉得现在可以了。

抱歉有任何英文错误