在C# WinForms中,为了实现SQLite3数据库的批量更新并与进度条联动,你需要将进度更新的逻辑抽取到一个单独的方法中,并通过事件或委托来通知外部控件更新进度条的值。这样,你就可以在调用更新方法时,同时更新UI控件。
下面是一个示例,展示了如何实现这一点:
首先,定义一个委托,用于通知更新进度条的值:
public delegate void ProgressUpdateDelegate(int value);
然后,在更新方法中添加一个事件,当每次执行SQL语句后触发这个事件:
public class DatabaseUpdater
{
public event ProgressUpdateDelegate ProgressUpdated;
public void Update(string DBsource, List<string> sqls)
{
string source = "Data Source=" + DBsource;
using SqliteConnection sqliteConn = new(source);
try
{
sqliteConn.Open();
int totalCount = sqls.Count;
ProgressBarUpdateHelper.Maximum = totalCount;
ProgressBarUpdateHelper.Value = 0;
ProgressBarUpdateHelper.Visible = true;
foreach (var item in sqls)
{
SqliteCommand cmd = new(item, sqliteConn);
cmd.Prepare();
cmd.ExecuteNonQuery();
// 触发事件更新进度条
OnProgressUpdated(1); // 假设每次增加1
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
sqliteConn.Close();
}
}
protected virtual void OnProgressUpdated(int value)
{
ProgressUpdated?.Invoke(value);
}
}
在WinForms应用程序中,你需要一个方法来接收这个事件并更新进度条。这通常在你的主窗体类中完成:
public partial class MainForm : Form
{
private DatabaseUpdater databaseUpdater;
public MainForm()
{
InitializeComponent();
databaseUpdater = new DatabaseUpdater();
databaseUpdater.ProgressUpdated += DatabaseUpdater_ProgressUpdated;
}
private void DatabaseUpdater_ProgressUpdated(int value)
{
// 更新UI,因此需要在控件线程中执行
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke(new ProgressUpdateDelegate(progressBar1.Value = value));
}
else
{
progressBar1.Value = value;
}
}
private void StartUpdatesButton_Click(object sender, EventArgs e)
{
// 假设你有一个列表sqls包含所有的SQL语句
List<string> sqls = ...;
databaseUpdater.Update("path_to_your_db", sqls);
}
}
在上面的代码中,MainForm
类订阅了 DatabaseUpdater
类的 ProgressUpdated
事件,并在事件处理器 DatabaseUpdater_ProgressUpdated
中更新了进度条的值。使用 InvokeRequired
和 Invoke
方法确保了UI更新在正确的线程上执行。
当你调用 StartUpdatesButton_Click
方法(可能是一个按钮的点击事件)时,它会启动批量更新过程,并且每次更新都会触发 ProgressUpdated
事件,从而更新UI中的进度条。
看你写过 JS。JS 里通常有一个很重要的概念,叫回调函数,可以把一个函数当作参数传递给另一个函数:
这段代码能理解吧?
在 C# 中也可以实现类似的逻辑,只不过它不叫回调函数,而是叫委托。C# 有两大类委托,一类是没有返回值的(也可以说返回值是
void
),是System.Action<>
;另一类是有返回值的,是System.Func<>
。用委托来改写你这段代码的话,就是:
当然了,这种写法其实很不 OOP。正常的写法应该是定义一个事件,由外部来监听这个事件再做处理。你既然在做 WinForm,那对事件应该不陌生,WinForm 里所有控件的各种触发都是事件。这个代码就不给了,AI 已经给出一段代码了。