C# WinForms修改SQLite后TreeView、CheckedListBox无法刷新问题求助
问题原因
- 核心错误:你在Form2中执行
new Form1().UpdateCheckedBoxList(sqlite_conn);时,创建了一个全新的、未在界面显示的Form1实例,你所有的更新操作都作用在这个后台隐藏实例上,对用户当前正在查看的原有Form1窗体没有任何影响,这是控件不刷新的核心原因。之前尝试的Refresh、Invalidate等方法都调用到了错误的实例上,自然无效。 - 次要问题:原有
UpdateCheckedBoxList方法直接调用AddRange添加数据,没有清空控件原有内容,即使实例正确,也会出现旧数据重复追加的问题,不是真正的刷新逻辑。 - 代码笔误:Form2中声明连接对象的类型写错,你写的是
SQLiteCommand sqlite_conn = new SQLiteConnection(...),类型不匹配会直接导致编译报错。
修复方案
步骤1:传递现有Form1实例给Form2
不要在Form2中新建Form1实例,而是在Form1打开Form2时,将自身实例传递给Form2:
- 首先修改Form2的构造函数,接收Form1实例并存储为私有字段:
public partial class Form2 : Form { // 存储传入的主窗体实例 private readonly Form1 _mainForm; // 自定义构造函数 public Form2(Form1 mainForm) { InitializeComponent(); _mainForm = mainForm; } }
- 在Form1中打开Form2的位置,传入自身实例:
// Form1中打开编辑窗体的代码 Form2 editForm = new Form2(this); editForm.Show();
步骤2:修改Form1的更新方法,实现正确的刷新逻辑
清空原有控件内容后再添加新查询到的数据:
public void UpdateCheckedBoxList(SQLiteConnection conn) { SQLiteCommand sqlite_cmd = conn.CreateCommand(); sqlite_cmd.CommandText = "SELECT * FROM Species; "; using SQLiteDataReader sqlite_datareader = sqlite_cmd.ExecuteReader(); List<string> myreader = new List<string>(); while (sqlite_datareader.Read()) { myreader.Add(sqlite_datareader.GetString(1)); } string[] species = myreader.ToArray(); // 先清空原有项,避免重复 checkedListBox1.Items.Clear(); checkedListBox1.Items.AddRange(species); }
步骤3:修改Form2的调用逻辑,使用传入的实例执行更新
修正类型错误,调用正确的实例方法,用完连接及时释放:
// 修正类型错误,SQLiteConnection不是SQLiteCommand using SQLiteConnection sqlite_conn = new SQLiteConnection("Data Source=" + @"C:\Users\" + Environment.UserName + @"\Documents\ddx project\ddx-database.db; Version = 3; New = True; Compress = True;"); sqlite_conn.Open(); // 用传入的现有Form1实例调用更新方法,不要新建实例 _mainForm.UpdateCheckedBoxList(sqlite_conn);
可选优化方案(低耦合)
如果不想在Form2中直接依赖Form1类型,可以用事件机制实现:
- 在Form2中定义编辑完成的事件,编辑完成后触发事件
- Form1订阅Form2的这个事件,收到通知后自己执行更新逻辑
这种方式两个窗体的耦合度更低,后续维护更方便。
内容的提问来源于stack exchange,提问作者MysticMia
相关产品推荐
相关产品推荐

