在属性中设置DataSource后更新DataGridView的数据源
Hey there! Let’s work through this DataGridView filtering problem you’re facing. I’ve run into similar snags when dealing with bound datasets, so here’s a solid approach that avoids the pitfalls of re-binding the DataSource every time:
Core Approach: Use DataView.RowFilter
Instead of re-setting the DataGridView’s DataSource manually (which can cause reset issues with column states, selection, etc.), leverage the DataView that’s already under the hood of your dataset. This lets you dynamically filter records without re-binding entirely.
Step 1: Initialize Your Binding Correctly
First, make sure your DataGridView is bound to a DataView (or use a BindingSource as an intermediary for extra flexibility) when you first set up the control:
// Assuming your dataset has a table named "Employees" DataView employeeView = new DataView(DsAll.Tables["Employees"]); // Or use a BindingSource for easier management BindingSource employeeSource = new BindingSource(); employeeSource.DataSource = employeeView; // Bind to the DataGridView dataGridView1.DataSource = employeeSource;
Step 2: Add TextBox Filter Logic
Hook up the TextChanged event of your TextBox to handle real-time filtering. This will update the filter as the user types:
private void txtFilter_TextChanged(object sender, EventArgs e) { // Get the underlying DataView from the DataGridView BindingSource bs = (BindingSource)dataGridView1.DataSource; DataView dv = (DataView)bs.List; string filterInput = txtFilter.Text.Trim(); // Escape single quotes to avoid filter syntax errors filterInput = filterInput.Replace("'", "''"); if (string.IsNullOrEmpty(filterInput)) { // Clear filter to show all records dv.RowFilter = string.Empty; } else { // Build filter for multiple fields (adjust field names to match your dataset) // Note: For numeric fields, convert to string first with Convert() dv.RowFilter = $"Convert(EmployeeID, 'System.String') LIKE '%{filterInput}%' OR DepartmentID LIKE '%{filterInput}%'"; } }
Key Notes to Avoid Issues
- Handle Numeric Fields: If fields like
EmployeeIDare numeric (int, decimal), useConvert(FieldName, 'System.String')to make the LIKE operator work—direct use of LIKE on numbers will throw errors. - Escape Special Characters: Always replace single quotes with two single quotes (
'→'') to prevent syntax exceptions in the filter string. - Skip Re-binding: Re-setting the DataSource every time you filter resets the DataGridView’s state (column widths, selected rows, etc.). Using
RowFilterpreserves all that.
Why Manual Binding Worked (But This Is Better)
When you manually set the DataSource, you’re essentially creating a new filtered view each time—but that’s inefficient and disrupts the user experience. Using the existing DataView keeps everything smooth while maintaining the control’s state.
内容的提问来源于stack exchange,提问作者Darrell

