使用DateTimePicker与TextBox筛选DataGridView时类型转换异常解决方案
问题解决方法
核心问题原因
你遇到的InvalidCastException是因为两种筛选操作的数据源处理逻辑不一致:
- 编号筛选(
txt_filterNum_TextChanged)会将DataGridView的数据源替换为新的BindingSource - 后续执行日期筛选(
timeFilter_ValueChanged)时,仍尝试将DataGridView.DataSource直接强制转换为DataTable,但此时数据源已经是BindingSource,转换失败
解决方案:统一用BindingSource管理筛选逻辑
全程使用同一个BindingSource作为数据源,组合所有筛选条件,避免数据源类型混乱。
步骤1:声明全局BindingSource
在窗体类中定义一个全局的BindingSource实例,作为DataGridView的唯一数据源:
private BindingSource _filterBindingSource = new BindingSource();
步骤2:初始化数据源
在窗体加载(如Form_Load)时,将原始DataTable绑定到这个BindingSource,再关联到DataGridView:
private void Form_Load(object sender, EventArgs e) { if (File.Exists(inputpath)) { // 替换成你加载日志数据到DataTable的实际代码 DataTable logDt = LoadLogDataToDataTable(); _filterBindingSource.DataSource = logDt; gridFilter.DataSource = _filterBindingSource; } }
步骤3:重构筛选逻辑,组合多条件
删除原来两个事件中的筛选代码,改为调用统一的筛选更新方法:
private void timeFilter_ValueChanged(object sender, EventArgs e) { UpdateCombinedFilter(); } private void txt_filterNum_TextChanged(object sender, EventArgs e) { UpdateCombinedFilter(); } // 统一处理所有筛选条件的组合 private void UpdateCombinedFilter() { if (!File.Exists(inputpath)) return; List<string> filterConditions = new List<string>(); // 1. 日期筛选:直接匹配指定日期 DateTime targetDate = timeFilter.Value.Date; // 针对DateTime类型列,用#包裹日期格式字符串 string dateCondition = $"Flight_Date = #{targetDate:yyyy-MM-dd}#"; filterConditions.Add(dateCondition); // 2. 编号筛选:仅当文本框不为空时添加条件 string numKeyword = txt_filterNum.Text.Trim(); if (!string.IsNullOrEmpty(numKeyword)) { string numColumn = gridFilter.Columns[indexRoleNum].HeaderText; // 转义单引号,避免筛选语法错误 string escapedKeyword = numKeyword.Replace("'", "''"); string numCondition = $"{numColumn} LIKE '%{escapedKeyword}%'"; filterConditions.Add(numCondition); } // 组合所有条件,用AND连接 _filterBindingSource.Filter = string.Join(" AND ", filterConditions); }
额外优化点
- 日期筛选简化:无需用
>=和<=同一个日期,直接用=即可匹配指定日期 - 单引号转义:处理用户输入带单引号的编号,避免筛选表达式语法错误
- 空值处理:当编号文本框为空时,自动移除该筛选条件,不影响日期筛选
内容的提问来源于stack exchange,提问作者newcomer
相关产品推荐
相关产品推荐

