C# DataGridView绑定数据源的方法

开始以前,先认识一下WinForm控件数据绑定的两种形式,简单数据绑定和复杂数据绑定。

1. 简单的数据绑定

例1

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connStr"].ToString()))
{ 

  SqlDataAdapter sda = new SqlDataAdapter("Select * From T_Class Where F_Type='Product' order by F_RootID,F_Orders", conn);
  DataSet Ds = new DataSet();
  sda.Fill(Ds, "T_Class");

  //使用DataSet绑定时,必须同时指明DateMember
  this.dataGridView1.DataSource = Ds;
  this.dataGridView1.DataMember = "T_Class";

  //也可以直接用DataTable来绑定
  this.dataGridView1.DataSource = Ds.Tables["T_Class"];
}

简单的数据绑定是将用户控件的某一个属性绑定至某一个类型实例上的某一属性。

采用如下形式进行绑定:引用控件.DataBindings.Add("控件属性", 实例对象, "属性名", true);

例2

从数据库中把数据读出来放到一个数据集中,比如List<>、DataTable,DataSet,我一般用List<>,

然后绑定数据源:

IList<student> sList=StudentDB.GetAllList();
DataGridView.DataSource=sList;

如果你没有设置DataGridView的列,它会自动生成所有列。

2. 复杂数据绑定

复杂的数据绑定是将一个以列表为基础的用户控件(例如:ComboBox、ListBox、ErrorProvider、DataGridView等控件)绑定至一个数据对象的列表。

基本上,Windows Forms的复杂数据绑定允许绑定至支持IList接口的数据列表。此外,如果想通过一个BindingSource组件进行绑定,还可以绑定至一个支持IEnumerable接口的数据列表。

对于复杂数据绑定,常用的数据源类型有(代码以DataGridView作为示例控件)。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace DataGridViewBindingData
{
 public partial class Form1 : Form
 {
  public Form1()
  {
    InitializeComponent();
  }

  private void button1_Click(object sender, EventArgs e)
  {
    //this.dataGridView1.DataSource = DataBindingByList1();
    //this.dataGridView1.DataSource = DataBindingByList2();
    //this.dataGridView1.DataSource = DataBindingByDataTable();
    this.dataGridView1.DataSource = DataBindingByBindingSource();
  }

  /// <summary>
  /// IList接口(包括一维数组,ArrayList等)
  /// </summary>
  /// <returns></returns>
  private ArrayList DataBindingByList1()
  {
    ArrayList Al = new ArrayList();
    Al.Add(new PersonInfo("a","-1"));
    Al.Add(new PersonInfo("b","-2"));
    Al.Add(new PersonInfo("c","-3"));
    return Al;
  }

  /// <summary>
  /// IList接口(包括一维数组,ArrayList等)
  /// </summary>
  /// <returns></returns>
  private ArrayList DataBindingByList2()
  {
    ArrayList list = new ArrayList();
    for (int i = 0; i < 10; i++)
    {
      list.Add(new DictionaryEntry(i.ToString(),i.ToString()+"_List"));
    }
    return list;
  }

  /// <summary>
  /// IListSource接口(DataTable、DataSet等)
  /// </summary>
  /// <returns></returns>
  private DataTable DataBindingByDataTable()
  {
    DataTable dt = new DataTable();
    DataColumn dc1 = new DataColumn("Name");
    DataColumn dc2 = new DataColumn("Value");

    dt.Columns.Add(dc1);
    dt.Columns.Add(dc2);

    for (int i = 1; i <= 10; i++)
    {
      DataRow dr = dt.NewRow();
      dr[0] = i;
      dr[1] = i.ToString() + "_DataTable";
      dt.Rows.Add(dr);
    }

    return dt;
  }

  /// <summary>
  /// IBindingListView接口(如BindingSource类)
  /// </summary>
  /// <returns></returns>
  private BindingSource DataBindingByBindingSource()
  {
    Dictionary<string, string> dic = new Dictionary<string, string>();
    for (int i = 0; i < 10; i++)
    {
      dic.Add(i.ToString(),i.ToString()+"_Dictionary");
    }
    return new BindingSource(dic,null);
  }
 }
}

上面代码中BindingSource的Datasource是一个结构类型DictionaryEntry,同样的DictionaryEntry并不能直接赋值给Combobox的DataSource,但通过BindingSource仍然可以间接实现。 这是因为:

BindingSource可以作为一个强类型的数据源。其数据源的类型通过以下机制之一固定。使用 Add 方法可将某项添加到 BindingSource 组件中。

将 DataSource 属性设置为一个列表、单个对象或类型。(这三者并不一定要实现IList或IListSource)

这两种机制都创建一个强类型列表。BindingSource 支持由其 DataSource 和 DataMember 属性指示的简单数据绑定和复杂数据绑定。 

总结:

根据DataSource绑定的对象的不同,可以有一下几种简单的绑定:

// DataSet 、DataTable
// 方式1
DataSet ds=new DataSet ();
this.dataGridView1.DataSource=ds.Table[0];
this.dataGridView1.DataSource = ds.Tables["表名"];
// 方式2
DataTable dt=new DataTable();
this.dataGridView1.DataSource=dt;

// DataView
DataView dv = new DataView();
this.dataGridView1.DataSource = dv;

// 设置了DataMember
DataSet ds=new DataSet ();
this.dataGridView1.DataSource = ds;
this.dataGridView1.DataMember = "表名";

// ArrayList
ArrayList Al = new ArrayList();
this.dataGridView1.DataSource = Al;

// dic
Dictionary<string, string> dic = new Dictionary<string, string>();
this.dataGridView1.DataSource = dic;

// List<Object>
this.dataGridVi.DataSource = new BindingList<Object>(List<Object>);

3. 实例

3.1 手动给dataGridView绑定数据源的方法

C#中手动给dataGridView绑定数据源,能够很自由地进行操作,但展示数据并没有C#自动添加数据源那么方便。可有时为了方便操作数据,我们更愿意手动连接数据源,代码如下:

conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Restaurant.mdb");//建立数据库连接
cmd = new OleDbCommand("select * from data", conn);//执行数据连接
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds);

this.dataGridView1.DataSource = ds.Tables[0];//数据源
this.dataGridView1.AutoGenerateColumns = false;//不自动
conn.Close();//关闭数据库连接

说明:解决DataGridView绑定了数据源无法更新保存当前行的问题

this.dataGridView.currentCell=null;//该行的作用是取消datagridview行的编辑状态
adapter.Update(userTable);

3.2 利用泛型集合向DataGridView中添加数据

List<>泛型集合:

private void Form1_Load(object sender, EventArgs e)
{
 //使用List<>泛型集合填充DataGridView
 List<Student> students = new List<Student>();
 Student hat = new Student("Hathaway", "12", "Male");
 Student peter = new Student("Peter","14","Male");
 Student dell = new Student("Dell","16","Male");
 Student anne = new Student("Anne","19","Female");
 students.Add(hat);
 students.Add(peter);
 students.Add(dell);
 students.Add(anne);
 this.dataGridView1.DataSource = students;
}

Dictionary<>泛型集合

private void Form1_Load(object sender, EventArgs e)
{
  //使用Dictionary<>泛型集合填充DataGridView
  Dictionary<String, Student> students = new Dictionary<String, Student>();
  Student hat = new Student("Hathaway", "12", "Male");
  Student peter = new Student("Peter","14","Male");
  Student dell = new Student("Dell","16","Male");
  Student anne = new Student("Anne","19","Female");
  students.Add(hat.StuName,hat);
  students.Add(peter.StuName,peter);
  students.Add(dell.StuName,dell);
  students.Add(anne.StuName,anne);
       //在这里必须创建一个BindIngSource对象,用该对象接收Dictionary<>泛型集合的对象
  BindingSource bs = new BindingSource();
       //将泛型集合对象的值赋给BindingSourc对象的数据源
  bs.DataSource = students.Values;
  this.dataGridView1.DataSource = bs;
}

3.3 利用SqlDataReader填充DataGridView

//使用SqlDataReader填充DataGridView
using (SqlCommand command = new SqlCommand("select * from product", DBService.Conn))
{
   SqlDataReader dr = command.ExecuteReader();
   BindingSource bs = new BindingSource();
   bs.DataSource = dr;
   this.dataGridView1.DataSource = bs;
}

3.4 利用SqlDataAdapter对象向DataGridView中添加数据

using (SqlDataAdapter da = new SqlDataAdapter("select * from Product", DBService.Conn))
{
   DataSet ds = new DataSet();
   da.Fill(ds);
   this.dataGridView1.DataSource = ds.Tables[0];
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2018-09-18

DataGridView使用自定义控件实现简单分页功能(推荐)

本例子使用自定义控件方法实现,数据库使用的是SQL Server,实现过程如下: 1.新建一个自定义控件,命名为:PageControl. 2.PageControl代码如下: public partial class PageControl : UserControl { //委托及事件 public delegate void BindPage(int pageSize, int pageIndex, out int totalCount); public event BindPage Bi

WinForm中DataGridView折叠控件【超好看】

刚到一家新公司,领导下发任务要用cs系统做一个表格折叠显示,这真是把我难倒了,自己工作6年一直以来都是做BS的系统.这如果在BS里面那太简单了,JqGrid默认都自带,可是DataGridview不支持折叠啊.自己一点经验没有,怎么办呢?于是上网搜了相关视频,资料,开始学习起来.最后借鉴源码封了这么一个东西,发出来分享下,也能让自己加深印象. 首先不多说,上图.如果大家感谢还不错,请继续往下阅读: 大概的效果就是这样. 上代码. 1.首先重写DataGridview,代码如下: public c

DataGridView展开与收缩功能实现

很多数据都有父节点与子节点,我们希望单击父节点的时候可以展开父节点下的子节点数据. 比如一个医院科室表,有父科室与子科室,点击父科室后,在父科室下面可以展现该科室下的所有子科室. 我们来说一下在DataGridView中如何实现这个功能. 首先,创建示例数据: 示例数据SQL create table Department ( ID int identity(1,1) not null, DName varchar(20) null, DparentId int null, Dtelphone

Winform在DataGridView中显示图片

首先,要添加图片列,绑定数据的时候会触发CellFormatting事件,在事件中取出图片路径,读取图片赋值给当前单元格. private void dataGridview1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (dataGridview1.Columns[e.ColumnIndex].Name.Equals("Image")) { string path = e.Valu

C#中DataGridView动态添加行及添加列的方法

本文实例讲述了C#中DataGridView动态添加行及添加列的方法.分享给大家供大家参考.具体如下: Datagridview添加列: DataGridViewTextBoxColumn acCode = new DataGridViewTextBoxColumn(); acCode.Name = "acCode"; acCode.DataPropertyName = "acCode"; acCode.HeaderText = "A/C Code&quo

C#自定义DataGridViewColumn显示TreeView

我们可以自定义DataGridView的DataGridViewColumn来实现自定义的列,下面介绍一下如何通过扩展DataGridViewColumn来实现一个TreeViewColumn 1.TreeViewColumn类 TreeViewColumn继承自DataGridViewColumn,为了动态给TreeViewColumn传入一个TreeView,这里暴露出一个公共属性_root,可以绑定一个初始化的TreeView. 另外需要重写DataGridCell类型的CellTempl

C#窗体控件DataGridView常用设置

在默认情况下,datagridview的显示效果: 1.禁用最后一行空白. 默认情况下,最后一行空白表示自动新增行,对于需要在控件中进行编辑,可以保留 dataGridView1.AllowUserToAddRows = false; 上述禁用,仅是将用户界面交互的自动新增行禁了,但还是可以通过代码:dataGridView1.Rows.Add();来新增一行空白. 2.禁用'delete'键的删除功能. 默认情况,鼠标选中一整行,按 删除键 可以删除当前一整行 dataGridView1.Al

如何:对Windows 窗体控件进行线程安全调用

示例 访问 Windows 窗体控件本质上不是线程安全的.如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包括争用情况和死锁.确保以线程安全方式访问控件非常重要. .NET Framework 有助于在以非线程安全方式访问控件时检测到这一问题.在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException,并提示消息:"从不是创建控件 contr

在多线程中调用winform窗体控件的实现方法

本文实例讲述了在C#中实现多线程中调用winform窗体控件的方法,对于C#程序设计的学习有着很好的借鉴参考价值.具体方法如下: 首先,由于Windows窗体控件本质上不是线程安全的.因此如果有两个或多个线程适度操作某一控件的状态(set value),则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包括争用和死锁的情况.于是在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationExceptio

浅谈C#跨线程调用窗体控件(比如TextBox)引发的线程安全问题

如何:对 Windows 窗体控件进行线程安全调用 访问 Windows 窗体控件本质上不是线程安全的. 如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态. 还可能会出现其他与线程相关的 Bug,例如争用情况和死锁. 确保以线程安全方式访问控件非常重要. 在未使用 Invoke 方法的情况下,从不是创建某个控件的线程的其他线程调用该控件是不安全的. 以下非线程安全的调用的示例. // This event handler creates a thread that

C#实现winform用子窗体刷新父窗体及子窗体改变父窗体控件值的方法

本文实例讲述了C#实现winform用子窗体刷新父窗体及子窗体改变父窗体控件值的方法.分享给大家供大家参考.具体如下: 第一种方法: 用委托,Form2和Form3是同一组 Form2 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows

C++获得其他程序窗体控件中信息的方法

本文实例讲述了C++获得其他程序窗体控件中信息的方法.分享给大家供大家参考.具体分析如下: 这里演示了获得其他程序窗体控件信息的方法, 用FindWindow API找到文本框句柄,用SendMessage(WM_GETTEXT)获得文本 #include <windows.h> BOOL CALLBACK EnumChildProc(HWND hWnd,LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev

iOS开发中UIImageView控件的常用操作整理

UIImageView,顾名思义,是用来放置图片的.使用Interface Builder设计界面时,当然可以直接将控件拖进去并设置相关属性,这就不说了,这里讲的是用代码. 1.创建一个UIImageView: 创建一个UIImageView对象有五种方法: 复制代码 代码如下: UIImageView *imageView1 = [[UIImageView alloc] init]; UIImageView *imageView2 = [[UIImageView alloc] initWith

ASP.NET单选按钮控件RadioButton常用属性和方法介绍

1.常用属性: (1)Checked属性:用来设置或返回单选按钮是否被选中,选中时值为true,没有选中时值为false. (2)AutoCheck 属性:如果 AutoCheck 属性被设置为 true(默认),那么当选择该单选按钮时,将自动清除该组中所有其他单选按钮.对一般用户来说,不需改变该属性,采用默认值(true)即可. (3)Appearance 属性:用来获取或设置单选按钮控件的外观.当其取值为 Appearance.Button 时,将使单选按钮的外观像命令按钮一样:当选定它时,

Android布局控件之常用linearlayout布局

LinearLayout是线性布局控件,它包含的子控件将以横向或竖向的方式排列,按照相对位置来排列所有的widgets或者其他的containers,超过边界时,某些控件将缺失或消失.因此一个垂直列表的每一行只会有一个widget或者是container,而不管他们有多宽,而一个水平列表将会只有一个行高(高度为最高子控件的高度加上边框高度).LinearLayout保持其所包含的widget或者是container之间的间隔以及互相对齐(相对一个控件的右对齐.中间对齐或者左对齐). xml属性

jquery 可拖拽的窗体控件实现代码

所以要引入JQUERY框架. 把我的这个控件代码放到一个js文件里面直接引入就可以了 控件代码 复制代码 代码如下: $.fn.myDrag = function() { var self = $(this); self.css("position", "absolute"); var p = self.position(); self.css({ left: p.left, top: p.top }); self.mousedown( function(event