使用STT将ComboBox和其他控件绑定到DataGridView





5.00/5 (3投票s)
使用STT(SQL Table Toolkit)将WinForm控件绑定到DataGridView并定义ComboBox的数据源
引言
在我们之前的文章中,我们介绍了STT
DLL库及其部分功能在实践中的应用。
本文的演示应用程序承接上一篇文章。如果有什么不清楚的地方,请阅读之前的文章。
在本文中,我们将演示如何使用STT轻松设置ComboBox
数据源以及如何将WinForm控件绑定到DataGridView
。
在我们的演示应用程序中,我们将绑定文本、浮点数、日期列以及两种类型的ComboBox
控件。一种的源来自STT表类,另一种则具有自定义源。我们还进行了按钮绑定,按钮的背景颜色、扁平样式和On_Click
事件都绑定到了DataGridView
。
背景
处理DataGridView
非常令人头疼,尤其是当涉及到ComboBox
时。为什么?为了实现真正的功能,如何在ComboBox
中实现?您必须用代码将其添加到DataGridView
中。而且每次ComboBox
源更改时都要这样做。单独处理一个ComboBox
就很费劲,然后是第二个、第三个……代码会越来越长,越来越混乱。如果您尝试从头开始将ComboBox
添加到DataGridView
,您就会明白我的意思。
Using the Code
将控件绑定到DataGridView
要使用STT将控件绑定到DataGridView
,我们只需要一行代码。
tblTable1.Columns["TextColumn"].BindToControl(textBox1);
dgv
单元格中的任何更改都会同步到控件,并且从控件到dgv
单元格的更改也会同步。在dgv
中移动时,将更改绑定控件中的值。
重要的是,绑定代码必须在将STT表类绑定到DataGridView
的代码之前。
tblTable1.Columns["TextColumn"].BindToControl(textBox1);
tblTable1.BindTableToDataGridView(dgvTable1);
无论我们想将哪种类型的控件绑定到DataGridView
,使用的代码都是相同的。
现在您可能会问:“ComboBox
怎么办?” 如果我将一个combobox
绑定到DatagridView
,它的datasource
在哪里?
如果我们使用STT将一个combobox
绑定到datagridview
,由此产生的datagridview combobox
将具有我们绑定的combobox
的datasource
。这将引我们进入文章的下一部分。
设置ComboBox的数据源
我们都知道如何设置ComboBox
的datasource
。即使很简单,也需要花费时间和代码。如果我们使用STT表,只需要一行代码。
STT.ComboBoxAdapter.EqualiseComboBoxes(comboBox1, tblTable2.ComboBox("PlayerName"));
这行代码做了什么?它获取一个没有源的combobox
控件(comboBox1
),并将其源设置为Table2
。它默认使用ID
列作为值成员,使用Name
列作为显示成员。如果我们的源表中没有Name
列,我们可以设置另一个列,例如PlayerName
。我们还可以将列的值成员从ID更改为其他列,但由于STT中每个表都应该有一个ID列,所以我们暂时保持原样。
之后,我们的combobox就有它的datasource
了,我们可以将其绑定到我们的datagridview
。
tblTable1.Columns["PlayerID"].BindToControl(comboBox2);
重要的是,我们要绑定到列的控件必须具有相同的DatagridViewColumn
控件类型。这意味着我们只能将一个combobox
绑定到我们表的combobox
列。如果我们查看Table1
,会发现PlayerID
列是一个combobox
列。
Columns.AddComboBox(this, "PlayerID", "Player");
STT有一个针对表类的事件,称为OnBindingColumnsToControls
。在将表绑定到DataGridView
之前,可以将此事件添加到表中。
tblTable1.OnBindingColumnsToControls += tblTable1_OnBindingColumnsToControls;
tblTable1.BindTableToDataGridView(dgvTable1);
在该事件中,我们可以设置控件的绑定代码。
void tblTable1_OnBindingColumnsToControls(object sender)
{
tblTable1.Columns["TextColumn"].BindToControl(textBox1);
STT.ComboBoxAdapter.EqualiseComboBoxes(comboBox1, tblTable2.ComboBox("PlayerName"));
tblTable1.Columns["PlayerID"].BindToControl(comboBox1);
}
每次我们使用表的上下文菜单并按“刷新字段”时,都会调用此事件。在将表绑定到dgv
之前,也会触发此事件。
为什么我们要使用“刷新字段”操作?
如果我们在DataGridView
中有一个ComboBox
,其源是应用程序中的另一个表。如果源表中的值或行已更改,我们仍然会获得在绑定ComboBox
控件时的数据。为了刷新我们的combobox
源,我们使用RefreshFields
这个操作。
这意味着,当datasource
通过STT设置的ComboBox
只拥有其源设置时的表数据快照。这也意味着应用程序不会在每次点击combobox
或在datagridview
中使用combobox
时从服务器加载其combobox
源。
ComboBox
源也可以在不使用STT的情况下设置。在这种情况下,我们还必须注意表列具有正确的DataGridView
列类型。
Columns.Add(this, "CustomComboBox", typeof(string), "", "(100)", "", false,
System.Data.SqlDbType.NVarChar, true, "Custom cbo",100,new DataGridViewComboBoxColumn());
将按钮绑定到DataGridView
向DataGridView
添加按钮很容易。但将其绑定到窗体控件是另一回事。如果我将一个按钮绑定到DataGridView
,我希望即使我按下DataGridView
上的按钮,On_Click
事件也能被触发。反之亦然。如果我在DataGridView
按钮上添加e
事件,它也应该在绑定的窗体控件按钮上触发。尝试演示应用程序并观察会发生什么。要将按钮的点击事件存储在我们的DataGridView
按钮中,我们需要在STT表类中重写OnButtonClick
事件。
public override void ButtonClick(object sender, DataGridViewCellEventArgs e)
{
if (DataGridView.Columns[e.ColumnIndex].Name == "Button")
{
MessageBox.Show("DataGridView button click", "Button Click");
}
}
演示应用程序
如果您打开演示应用程序,您会发现绑定7种不同类型控件的所有代码都非常少。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace STTDemoProject
{
public partial class Table1Form : Form
{
Table1 tblTable1 = new Table1();
Table2 tblTable2 = new Table2();
public Table1Form()
{
InitializeComponent();
DataTable tblCustomSource = new DataTable();
tblCustomSource.Columns.Add("Value", typeof(string));
tblCustomSource.Columns.Add("Display", typeof(string));
tblCustomSource.Rows.Add("Item1", "Item1");
tblCustomSource.Rows.Add("Item2", "Item2");
tblCustomSource.Rows.Add("Item3", "Item3");
comboBox2.DataSource = tblCustomSource;
comboBox2.ValueMember = "Value";
comboBox2.DisplayMember = "Dislay";
tblTable1.OnBindingColumnsToControls += tblTable1_OnBindingColumnsToControls;
tblTable1.BindTableToDataGridView(dgvTable1);
}
void tblTable1_OnBindingColumnsToControls(object sender)
{
tblTable1.Columns["TextColumn"].BindToControl(textBox1);
tblTable1.Columns["FloatColumns"].BindToControl(textBox2);
tblTable1.Columns["DateColumn"].BindToControl(textBox3);
tblTable1.Columns["CheckColumn"].BindToControl(checkBox1);
STT.ComboBoxAdapter.EqualiseComboBoxes(comboBox1, tblTable2.ComboBox("PlayerName"));
tblTable1.Columns["PlayerID"].BindToControl(comboBox1);
tblTable1.Columns["CustomComboBox"].BindToControl(comboBox2);
tblTable1.Columns["Button"].BindToControl(button1);
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("From Control click", "Button Click");
}
}
}
要使用演示应用程序,请设置对STT DLL文件的引用,运行它并设置正确的SQL连接,使用密码“123
”以备份用户身份登录,然后尽情享受吧。 :)
特点
- 绑定
TextBox
也会绑定TextBox
的自动完成设置。 ComboBox
的自动完成设置也将绑定到DataGridView
。DataGridView
单元格的背景颜色将与其绑定的控件同步。- 绑定的按钮将同步其扁平样式和颜色与其绑定的控件。
- 使用STT集成过滤器在
ComboBox
列中将只显示ComboBox
可用的值。
限制
我没有使用源是其项目列表的ComboBox
。因此,它无法与此类combobox
一起工作。一个简单的解决方法是为textbox
设置autocomplete
。如果我有时间,列表源的combobox
也将起作用。 :)
关注点
在接下来的文章中,我们将研究STT类库的更新和错误日志工具。
历史
- 2015年3月25日 - 首次发布