一步一步学习Winform系列6:多重条件搜索的设计与实现
3、父子窗体的运用
在datagridView的智能面板上弹出相应的面板任务,点击选择数据源的下拉菜单,如果没有数据源请选择添加项目数据源
开始跟着向导一路设置datagridView的数据源,这种方式比我们之前手动书写sql语句来得快。选择数据库,点击下一步。
选择数据集(无截图),点击下一步设置数据库连接。
连接上数据库后,可以直接看到当前数据库的所有表,这里我们准备对产品表进行多重条件查找,所以勾选上products即可。
完成后就可以看到界面的下方多出了三个控件
这里的所有可用产品必须满足两个条件:为库存中所有库存量大于0且未被中止销售的商品。所以单纯的向导设置还不能满足要求。这时我们可以点击Dataset的智能面板打开它的“数据集编辑器编辑”
添加查询,可使用查询分析器
TableAdpter查询配置向导,下一步查询类型可选择Select(多行),下一步
还可以在向导中使用查询生成器
设置完成后将datagridView的数据源设置为这个productsBingingSource
数据源的加载时间在之前的窗体中,我们已经学习过了。那么什么是自动完成功能呢?就是窗体控件能模仿百度搜索时动作,在未输入完成产品名称或供应商名称前提前将搜索结果反馈到界面中。效果如图:
我们把数据加载功能放在了窗体的加载事件中。关键实现代码有(为加强效果对比,供应商名称中并没有设置自动完成功能)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private void 查看可用产品_Load(object sender, EventArgs e) { // TODO: 这行代码将数据加载到表“northwindDataSet1.产品”中。您可以根据需要移动或删除它。 this.产品TableAdapter.Fill(this.northwindDataSet1.产品); //加载本窗体时,自动加载所有可用产品 //DatagridView的绑定方法直接采用northwindDataSet,在设计界面直接设置完成 //绑定类别comboBox的数据源 DataSet ds = SqlHelper.ExecuteDataset(SqlHelper.GetConnection(), CommandType.Text, "SELECT * From 类别"); cbx类别名称.DataSource = ds.Tables[0]; cbx类别名称.ValueMember = "类别ID"; cbx类别名称.DisplayMember = "类别名称"; ////自动完成 cbx类别名称.AutoCompleteMode = AutoCompleteMode.SuggestAppend; cbx类别名称.AutoCompleteSource = AutoCompleteSource.CustomSource; AutoCompleteStringCollection coll = new AutoCompleteStringCollection(); for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { coll.Add(ds.Tables[0].Rows[i]["类别名称"].ToString());//这个地方是自动完成的下拉框的显示内容 } cbx类别名称.AutoCompleteCustomSource = coll; //绑定供应商comboBox的数据源 DataSet ds供应商 = SqlHelper.ExecuteDataset(SqlHelper.GetConnection(), CommandType.Text, "SELECT * From 供应商"); cbx供应商名称.DataSource = ds供应商.Tables[0]; cbx供应商名称.ValueMember = "供应商ID"; cbx供应商名称.DisplayMember = "公司名称"; cbx供应商名称.SelectedIndex = -1; cbx类别名称.SelectedIndex = -1; cbx类别名称.Text = string.Empty; cbx供应商名称.Text = string.Empty; }
每次用户点击清空时,应清空数据库的查询条件,尤其是commbox内的内容,否则会导致搜索结果不如预期。因此这里的清空很重要。
private void btn清空_Click(object sender, EventArgs e) { tbx产品名称.Text = string.Empty; cbx供应商名称.Text = string.Empty; cbx供应商名称.SelectedIndex = -1; cbx类别名称.SelectedIndex = -1; cbx类别名称.Text = string.Empty; tbx最高价格.Text = string.Empty; tbx最低价格.Text = string.Empty; }
点击之前需要做多个验证与判断,首先先判断产品价格的两个文本框必须输入的是数字,这里需要用到正则表达式。(该函数被抽象出来放在CommonFunc类中,方便其他地方调用)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#region 判断文本框输入是否为数字 /// <summary> /// 名称:判断查找可用产品的价格文本框输入是否为数字,可以是小数\正整数 /// </summary> /// <param name="strInput"></param> /// <returns></returns> public static bool IsNumberForInput(string strInput) { if (strInput != string.Empty) { string pattern浮点数 = "^[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$"; string pattern正整数="d*[1-9]\\d*$"; Regex rx浮点数 = new Regex(pattern浮点数); Regex rx正整数 = new Regex(pattern正整数); if (rx浮点数.IsMatch(strInput) || rx正整数.IsMatch(strInput)) return true; else return false; } else return true; } #endregion
对于多重条件搜索,最难的地方点击搜索后,SQL条件语句的拼凑与模糊查询的设置。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private void btn搜索_Click(object sender, EventArgs e) { if (!CommonFunc.IsNumberForInput(tbx最高价格.Text) || !CommonFunc.IsNumberForInput(tbx最低价格.Text)) { MessageBox.Show("产品价格只能填入数字!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (tbx最低价格.Text != string.Empty && tbx最高价格.Text == string.Empty) { MessageBox.Show("产品价格的最高价格不能为空,请填写完整!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (tbx最高价格.Text != string.Empty && tbx最低价格.Text == string.Empty) { MessageBox.Show("产品价格的最低价格不能为空,请填写完整!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { //SQL查询语句,默认情况下为查找所有可用产品 DataSet ds = new DataSet(); string strQuery = "SELECT * FROM 产品 WHERE 中止='False' AND 库存量>0 "; //拼凑sql的条件语句 string strCondition = ""; if (tbx产品名称.Text != string.Empty) { strCondition += "AND 产品名称 like '%" + tbx产品名称.Text + "%' "; } if (cbx供应商名称.SelectedValue != null) { strCondition += "AND 供应商ID=" + cbx供应商名称.SelectedValue.ToString() + " "; } if (cbx类别名称.SelectedValue != null) { strCondition += "AND 类别ID=" + cbx类别名称.SelectedValue.ToString() + " "; } if (tbx最低价格.Text != string.Empty && tbx最高价格.Text != string.Empty) { strCondition += "AND 单价>= " + tbx最低价格.Text + " AND 单价<=" + tbx最高价格.Text; } ds = SqlHelper.ExecuteDataset(SqlHelper.GetConnection(), CommandType.Text, strQuery + strCondition); dataGridView.DataSource = ds.Tables[0]; } }
代码填写完成之后,运行可以看到以下效果:
默认打开此界面与没有搜索条件时点击搜索,预期效果为预览出所有当前还未中止销售且库存量为正数的产品记录。
查询时可以任意输入几个条件的组合进行搜索
大家可以考虑一下,如果使用的是中文字段的数据库表,我们的程序应该如何修改?
下一课我们进行的是生产订单功能模块的设计与实现。可以参考一下界面,先完成两个窗体的设计。
生产新订单窗体
点击此订单上的新增按钮后,弹出新增订单明细窗体