将checklistbox项保存到设置中

本文关键字:设置 保存 checklistbox | 更新日期: 2023-09-27 18:14:24

我试图在用户设置中维护CheckedListBox中的检查项列表,然后在应用程序加载时重新加载它们。

在我的Settings.settings文件中,我添加了以下内容:

<Setting Name="obj" Type="System.Windows.Forms.CheckedListBox.ObjectCollection" Scope="User">
    <Value Profile="(Default)" />
</Setting>

并且,在chkList_ItemCheck上,我正在做以下操作:

Properties.Settings.Default.obj = chkList.Items;
Properties.Settings.Default.Save()

但由于某种原因,当我退出应用程序,重新打开,并检查Properties.Settings.Default.obj的值,它是null

我做错了什么?

将checklistbox项保存到设置中

由于CheckedListBox.CheckedItems属性不能绑定到设置中,你应该添加一个字符串属性,并在设置中以逗号分隔的字符串存储检查项,并在关闭表单时保存设置,并在表单加载时设置CheckedListBox的检查项

保存CheckedListBoxCheckedItems:

  1. Properties文件夹中添加Settings文件到你的项目中,或者如果你有的话打开它。
  2. 添加名为CheckedItems
  3. 的字符串设置属性
  4. Load事件中,从设置中读取选中项,并使用SetItemChecked在CheckedListBox中设置选中项。
  5. FormClosing事件中,读取CheckedListBox的CheckedItems并保存为逗号分隔的字符串。

代码:

private void Form1_Load(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(Properties.Settings.Default.CheckedItems))
    {
        Properties.Settings.Default.CheckedItems.Split(',')
            .ToList()
            .ForEach(item =>
            {
                var index = this.checkedListBox1.Items.IndexOf(item);
                this.checkedListBox1.SetItemChecked(index, true);
            });
    }

}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    var indices = this.checkedListBox1.CheckedItems.Cast<string>()
        .ToArray();
    Properties.Settings.Default.CheckedItems = string.Join(",", indices);
    Properties.Settings.Default.Save();
}

我怎么知道它不能绑定到设置?

作为第一个证据,对于设计器模式中的每个控件,在属性网格中,您可以检查+(ApplicationSettings) (PropertyBinding)[…]查看支持属性绑定的属性列表。

此外,你应该知道"应用程序设置使用Windows窗体数据绑定架构来提供设置对象和组件之间设置更新的双向通信。"[1]

例如,当您将CheckedListBoxBackColor属性绑定到MyBackColor属性时,设计器为其生成以下代码:

this.checkedListBox1.DataBindings.Add(
    new System.Windows.Forms.Binding("BackColor", 
    global::StackSamplesCS.Properties.Settings.Default, "MyBackColor", true,
    System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));

现在让我们看看属性定义[2]:

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CheckedListBox.CheckedItemCollection CheckedItems { get; }

属性或索引CheckedListBox.CheckedItems不能为因为它是只读的

有更好的方法吗?

这个属性的简短回答是No。

假设我们有一个属性MyCheckedItems:

[UserScopedSetting()]
public CheckedListBox.CheckedItemCollection MyCheckedItems
{
    get
    {
        return ((CheckedListBox.CheckedItemCollection)this["MyCheckedItems"]);
    }
    set
    {
        this["MyCheckedItems"] = (CheckedListBox.CheckedItemCollection)value;
    }
}

如何实例化CheckedListBox.CheckedItemCollection ?

类型CheckedListBox.CheckedItemCollection没有public定义的构造函数

所以我们不能实例化它。CheckedListBox内部使用的唯一构造函数是[2]:

internal CheckedItemCollection(CheckedListBox owner)

此外,向该集合添加项的唯一方法是CheckedItemCollection的内部方法:

internal void SetCheckedState(int index, CheckState value)

所以我们不能为这个属性做一个更好的解决方案。

更多信息:

  • 对于设计器模式中的每个控件,在属性网格中,您可以检查+(ApplicationSettings) (PropertyBinding)[…]查看支持属性绑定的属性列表。
  • 设置序列化以这种方式工作,它首先尝试在类型的相关TypeConverter上调用ConvertToStringConvertFromString。如果不成功,则使用XML序列化。[1]因此,如果你没有面对只读属性或无构造函数类,你可以使用自定义TypeConverter或自定义序列化器序列化值。