C# WinForm中保存用户添加的ListBox项(非文本文件方式)
嘿,我刚好做过类似的需求,给你几个靠谱的实现方案,都不用文本文件,亲测能搞定ListBox项的持久化:
方案一:使用应用程序设置(Settings)
这是最简单的方案,适合存储少量列表项,也是微软官方推荐的轻量级持久化方式。
步骤:
打开你的WinForm项目,右键项目 → 属性 → 切换到「设置」标签页。
点击“创建设置文件”(如果还没有的话),然后添加一个设置:
- 名称:
ListBoxSavedItems - 类型:
System.Collections.Specialized.StringCollection - 范围:
用户(这样每个用户都有自己的独立保存数据) - 值:留空即可
- 名称:
在窗体代码里实现加载和保存逻辑:
using System.Collections.Specialized; using System.Configuration; public partial class MainForm : Form { public MainForm() { InitializeComponent(); } // 窗体加载时恢复ListBox项 private void MainForm_Load(object sender, EventArgs e) { if (Properties.Settings.Default.ListBoxSavedItems != null) { foreach (string item in Properties.Settings.Default.ListBoxSavedItems) { listBox1.Items.Add(item); } } } // 添加项的按钮点击事件 private void btnAddItem_Click(object sender, EventArgs e) { string newItem = "Item 1"; // 这里可以替换成用户输入的内容 listBox1.Items.Add(newItem); // 初始化空集合 if (Properties.Settings.Default.ListBoxSavedItems == null) { Properties.Settings.Default.ListBoxSavedItems = new StringCollection(); } Properties.Settings.Default.ListBoxSavedItems.Add(newItem); // 保存设置到本地 Properties.Settings.Default.Save(); } // 可选:删除项时同步更新设置 private void btnDeleteItem_Click(object sender, EventArgs e) { if (listBox1.SelectedIndex != -1) { string selectedItem = listBox1.SelectedItem.ToString(); listBox1.Items.Remove(selectedItem); Properties.Settings.Default.ListBoxSavedItems.Remove(selectedItem); Properties.Settings.Default.Save(); } } }
优缺点:
- ✅ 优点:零额外依赖、代码量少、易维护
- ❌ 缺点:仅适合存储少量简单数据,不支持复杂数据结构
方案二:使用Windows注册表
如果不想用应用设置,可以把数据存在注册表的用户分支下(避免系统级权限问题)。
步骤:
- 引用
Microsoft.Win32命名空间 - 实现读取和写入逻辑:
using Microsoft.Win32; public partial class MainForm : Form { // 自定义注册表路径,建议用自己的应用名作为子键 private const string RegistryPath = @"Software\MyWinApp\ListBoxItems"; public MainForm() { InitializeComponent(); } private void MainForm_Load(object sender, EventArgs e) { using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryPath)) { if (key != null) { // 读取所有注册表值,逐个添加到ListBox string[] itemNames = key.GetValueNames(); foreach (string name in itemNames) { string itemValue = key.GetValue(name)?.ToString(); if (!string.IsNullOrEmpty(itemValue)) { listBox1.Items.Add(itemValue); } } } } } private void btnAddItem_Click(object sender, EventArgs e) { string newItem = "Item 1"; listBox1.Items.Add(newItem); // 创建或打开注册表项 using (RegistryKey key = Registry.CurrentUser.CreateSubKey(RegistryPath)) { if (key != null) { // 用时间戳作为值名称,避免重复 string valueName = DateTime.Now.Ticks.ToString(); key.SetValue(valueName, newItem); } } } // 删除项的逻辑 private void btnDeleteItem_Click(object sender, EventArgs e) { if (listBox1.SelectedIndex != -1) { string selectedItem = listBox1.SelectedItem.ToString(); listBox1.Items.Remove(selectedItem); using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryPath, true)) { if (key != null) { string[] itemNames = key.GetValueNames(); foreach (string name in itemNames) { if (key.GetValue(name)?.ToString() == selectedItem) { key.DeleteValue(name); break; } } } } } } }
优缺点:
- ✅ 优点:无需额外文件,系统级存储
- ❌ 缺点:代码比应用设置繁琐,仅适合简单数据存储
方案三:使用轻量级数据库(SQLite)
如果你的ListBox项数量多或者需要复杂查询,SQLite是个不错的选择——它是文件型数据库,无需安装额外服务。
步骤:
- 安装NuGet包:
Microsoft.Data.Sqlite(微软维护的版本,推荐) - 实现数据库初始化和CRUD逻辑:
using Microsoft.Data.Sqlite; using System.Data; public partial class MainForm : Form { // 数据库文件存放在用户的应用数据目录 private string _dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyWinApp", "ListBoxItems.db"); public MainForm() { InitializeComponent(); // 初始化数据库和表 InitializeDatabase(); } private void InitializeDatabase() { // 创建存储目录 Directory.CreateDirectory(Path.GetDirectoryName(_dbPath)); using (SqliteConnection conn = new SqliteConnection($"Data Source={_dbPath}")) { conn.Open(); // 创建存储项的表 string createTableSql = @" CREATE TABLE IF NOT EXISTS SavedItems ( Id INTEGER PRIMARY KEY AUTOINCREMENT, ItemText TEXT NOT NULL )"; using (SqliteCommand cmd = new SqliteCommand(createTableSql, conn)) { cmd.ExecuteNonQuery(); } } } private void MainForm_Load(object sender, EventArgs e) { using (SqliteConnection conn = new SqliteConnection($"Data Source={_dbPath}")) { conn.Open(); string querySql = "SELECT ItemText FROM SavedItems"; using (SqliteCommand cmd = new SqliteCommand(querySql, conn)) { using (SqliteDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { listBox1.Items.Add(reader.GetString(0)); } } } } } private void btnAddItem_Click(object sender, EventArgs e) { string newItem = "Item 1"; listBox1.Items.Add(newItem); using (SqliteConnection conn = new SqliteConnection($"Data Source={_dbPath}")) { conn.Open(); string insertSql = "INSERT INTO SavedItems (ItemText) VALUES (@ItemText)"; using (SqliteCommand cmd = new SqliteCommand(insertSql, conn)) { cmd.Parameters.AddWithValue("@ItemText", newItem); cmd.ExecuteNonQuery(); } } } private void btnDeleteItem_Click(object sender, EventArgs e) { if (listBox1.SelectedIndex != -1) { string selectedItem = listBox1.SelectedItem.ToString(); listBox1.Items.Remove(selectedItem); using (SqliteConnection conn = new SqliteConnection($"Data Source={_dbPath}")) { conn.Open(); string deleteSql = "DELETE FROM SavedItems WHERE ItemText = @ItemText"; using (SqliteCommand cmd = new SqliteCommand(deleteSql, conn)) { cmd.Parameters.AddWithValue("@ItemText", selectedItem); cmd.ExecuteNonQuery(); } } } } }
优缺点:
- ✅ 优点:支持大量数据、复杂查询、扩展性强
- ❌ 缺点:需要引入NuGet包,代码量相对较多
内容的提问来源于stack exchange,提问作者user6246171
相关产品推荐
相关产品推荐

