65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2015年3月25日

CPOL

6分钟阅读

viewsIcon

59398

downloadIcon

83

使用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将具有我们绑定的comboboxdatasource。这将引我们进入文章的下一部分。

设置ComboBox的数据源

我们都知道如何设置ComboBoxdatasource。即使很简单,也需要花费时间和代码。如果我们使用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日 - 首次发布
© . All rights reserved.