如何用C#和SQLite从WPF DataGrid选中行更新数据库?
实现步骤
1. 在ViewModel中获取DataGrid选中的多行
DataGrid的SelectedItems无法直接双向绑定,可通过按钮的CommandParameter将选中项传递给命令:
XAML修改
<Button Content="标记为已处理" Command="{Binding MarkAsProcessedCommand}" CommandParameter="{Binding ElementName=YourDataGrid, Path=SelectedItems}"/>
ViewModel中定义命令
假设你已有基础的RelayCommand实现,在ViewModel中添加命令逻辑:
public ICommand MarkAsProcessedCommand { get; } public YourViewModel() { MarkAsProcessedCommand = new RelayCommand<IEnumerable>(ExecuteMarkAsProcessed); } private void ExecuteMarkAsProcessed(IEnumerable selectedItems) { var selectedInvoices = selectedItems.Cast<Invoices>().ToList(); if (!selectedInvoices.Any()) return; // 后续执行数据库更新与UI同步操作 }
2. 批量更新SQLite数据库
无需获取所有列数据,仅需选中行的Id即可。利用SQLite的IN子句实现批量更新,同时通过参数化查询避免SQL注入:
private void UpdateSelectedInvoices(List<Invoices> selectedInvoices) { if (selectedInvoices.Count == 0) return; // 构造参数占位符,如@Id0、@Id1... var idParameters = selectedInvoices.Select((_, index) => $"@Id{index}"); string sql = $"UPDATE mydataTable SET Info = 'Processed' WHERE Id IN ({string.Join(", ", idParameters)})"; using (SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection)) { // 逐个添加Id参数 for (int i = 0; i < selectedInvoices.Count; i++) { command.Parameters.AddWithValue($"@Id{i}", selectedInvoices[i].Id); } try { m_dbConnection.Open(); command.ExecuteNonQuery(); } finally { m_dbConnection.Close(); } } }
3. 同步UI数据(遵循MVVM)
由于DataGrid列绑定为OneWay,更新数据库后需同步ViewModel中的数据,触发UI自动刷新:
首先确保Invoices模型补充Info属性:
private string _info; public string Info { get => _info; set => SetValue(ref _info, value); }
然后添加UI同步逻辑:
private void SyncUiWithDatabase(List<Invoices> selectedInvoices) { foreach (var invoice in selectedInvoices) { invoice.Info = "Processed"; // 模型继承的ViewModelBase会自动触发PropertyChanged通知UI更新 } // 若需刷新ICollectionView,调用以下方法 YourCollectionView.Refresh(); }
整合命令执行逻辑
将数据库更新与UI同步整合到命令执行方法中:
private void ExecuteMarkAsProcessed(IEnumerable selectedItems) { var selectedInvoices = selectedItems.Cast<Invoices>().ToList(); if (!selectedInvoices.Any()) return; try { UpdateSelectedInvoices(selectedInvoices); SyncUiWithDatabase(selectedInvoices); } catch (Exception ex) { // 异常处理,如弹出提示 MessageBox.Show($"更新失败:{ex.Message}"); } }
关键注意事项
- 安全规范:必须使用参数化查询,禁止直接拼接Id到SQL语句,避免SQL注入风险。
- MVVM原则:所有操作均在ViewModel中完成,未直接操作DataGrid控件,符合视图与逻辑分离的要求。
- 资源管理:用
using语句管理SQLiteCommand,通过finally块确保数据库连接关闭,避免连接泄漏。
内容的提问来源于stack exchange,提问作者Tamal Banerjee
相关产品推荐
相关产品推荐

