C#中如何从另一个类访问窗体中的DataGridView控件?
如何从Book类访问Form8中的DataGridView控件?
首先得指出你现有代码里的核心问题:你在searchBook方法里新建了一个Form8实例,但这个实例和用户正在操作的那个窗体根本不是同一个——就像你复制了一个新的窗口,给它的表格填了数据,但用户看不到这个新窗口,自然看不到数据变化。
下面给你两种靠谱的解决方法,从简单快速到更符合设计原则的都有:
方法1:直接传递当前Form8实例到Book类的方法里
这种方法最直接,适合快速修改现有代码:
修改Book类的代码
public void searchBook(string valueToSearch, Form8 currentForm) { DynamicConnection con = new DynamicConnection(); con.mysqlconnection(); // 注意:这里暂时保留你的原有SQL写法,后面会提醒你替换成参数化查询 con.sqlquery("select * from TBL_Book where CONCAT(ISBN_No,BookName,Author,Publisher,CategoryID,ReOrderLevel)like '%" + valueToSearch + "%'"); con.dataread(); con.datatable(); con.table.Load(con.datareader); // 直接操作传入的、用户正在使用的窗体实例 currentForm.DGV.DataSource = con.table; }
在Form8里调用方法时传入当前实例
比如在你的搜索按钮点击事件里:
private void btnSearch_Click(object sender, EventArgs e) { Book bookManager = new Book(); // 用this关键字把当前Form8实例传进去 bookManager.searchBook(txtSearch.Text, this); }
方法2:让Book类只负责查数据,Form8自己处理UI(更推荐)
这种方法更符合单一职责原则——Book类只负责数据逻辑,不直接操作UI控件,代码会更易维护和扩展:
修改Book类的代码,让方法返回查询结果
public DataTable searchBook(string valueToSearch) { DynamicConnection con = new DynamicConnection(); con.mysqlconnection(); // 强烈替换成参数化查询,彻底避免SQL注入风险 con.sqlquery("select * from TBL_Book where CONCAT(ISBN_No,BookName,Author,Publisher,CategoryID,ReOrderLevel)like @searchValue"); // 假设你的DynamicConnection类有添加参数的方法(如果没有,建议补上这个功能) con.addParameter("@searchValue", "%" + valueToSearch + "%"); con.dataread(); con.datatable(); con.table.Load(con.datareader); return con.table; }
在Form8里接收数据并设置到DataGridView
private void btnSearch_Click(object sender, EventArgs e) { Book bookManager = new Book(); DataTable searchResult = bookManager.searchBook(txtSearch.Text); // 自己把数据源绑定到DataGridView this.DGV.DataSource = searchResult; }
重要提醒:一定要避免SQL注入!
你当前的SQL语句是直接拼接用户输入的字符串,这属于高危写法,很容易被黑客利用SQL注入攻击你的数据库。一定要用参数化查询,就像方法2里展示的那样,把用户输入作为参数传递,而不是直接拼进SQL语句里。
内容的提问来源于stack exchange,提问作者Kith
相关产品推荐
相关产品推荐

