数据绑定之DataBinding细解

在C#操作数据库过程中,针对一般的文本控件,比如TextBox,Label等,我们赋值直接使用类似TextBox.Text=****的方式来进行,这种方式从某种意义上来说的确是最简便的方式,但是对于复杂一些的空间,比如说DataGridView,这个时候,绑定数据源我们一般使用DataGridView1.DataSource=****的方式来进行,如果数据源稍微有更改,那么只需要重新调用绑定一遍即可。可以说这种方式是单向的,也即从数据库到UI,但是有没有一种方式能够实现数据源改变的时候,不用重新绑定DataGridView就让它能够自动刷新数据呢,当然,这里要提到的就是DataBinding了。

下面来一步一步的进行。

首先来看看示例一,主要是利用TextBox的DataBindings方式来进行数据绑定:

在界面上放置一个TextBox,名称为textBox1,再放置一个TrackBar,名称为trackBar1,然后编写绑定代码如下:

textBox1.DataBindings.Add("Text", trackBar1, "Value", false, DataSourceUpdateMode.OnPropertyChanged);

这样,我们就可以非常明显的看到,当textBox1文本框里面的值改变的时候,trackBar1的值跟着改变;当trackBar1的值改变的时候,文本框中的值也跟着改变,看来,这种改变是双向的。

在这里我要啰嗦下DataBindings的用法,虽然网上和MSDN上对其的介绍已经是多如牛毛:

复制代码
 /************************************************
  * 第一个值:要绑定到TextBox的什么地方
  * 第二个值:数据源是什么
  * 第三个值:应该取数据源的什么属性
  * 第四个值:是否开启数据格式化
  * 第五个值:在什么时候启用数据源绑定
  * *********************************************/
  textBox1.DataBindings.Add("Text", trackBar1, "Value", false, DataSourceUpdateMode.OnPropertyChanged);
复制代码

上面只是一种最简便的方式,但是我们能不能绑定自己定义的类,把自定义类当做数据源呢?当然能。DataBindings能够接受任意类型的Object类型的数据源。

定义类如下:

  public class MyDataSource
    {
        public string Myvalue { get; set; }
    }

然后我们在代码中可以按照如下方式绑定:

复制代码
 MyDataSource mydatasource = new MyDataSource();  //应用于第二种方式

 private void mainFrm_Load(object sender, EventArgs e)
 {
   /*********************************************
    * 这个主要就是通过一个外部的类,当做数据源
    * *********************************************/ 
    mydatasource.Myvalue = "这是个测试";
    textBox2.DataBindings.Add("Text",mydatasource,"Myvalue",false,DataSourceUpdateMode.OnPropertyChanged);
复制代码

那么,当我们在界面上看的时候,就会发现,textBox2中显示的是“这是个测试”五个字。

但是,有时候定义类太麻烦,能不能通过给定的属性来充当数据源呢?这个当然也能,这样的方式,只适合在一些应用很简单的场合,可以按照如下方式绑定:

复制代码
  public int Num { get; set; }  //应用于第三种方式

  private void mainFrm_Load(object sender, EventArgs e)
  {
       /*****************************************
        *这个主要就是通过本身拥有的属性,当做数据源
         ****************************************/
        Num = 5;
        textBox3.DataBindings.Add("Text",this,"Num", false,DataSourceUpdateMode.OnPropertyChanged);
  }            
复制代码

这样,我们就可以把一个类内部的属性当做数据源来使用了。需要注意的是,之所以利用this来充当数据源,是因为窗体他本身就是一个类,Num充当了这个类中的属性而已。

接下来,我们就需要说到重头戏了,DataGridView的表现形式。

对于这个数据控件,我相信大家都不会陌生,但是如何实现自定义的数据绑定呢?请看代码:

这里我们首先应该定义一个Model类,以便保存数据:

    public class BlogNew
    {
        public int BlogID { get; set; }
        public string BlogTitle { get; set; }
    }

然后我们利用List<T>泛型来保存数据,最后是将这个数据源绑定到dataGridView1控件上:

复制代码
 public List<BlogNew> blogNews { get; set; }  //应用于第四种方式

 private void mainFrm_Load(object sender, EventArgs e)
 {
            blogNews = new List<BlogNew>();
            blogNews.Add(new BlogNew { BlogID = 1, BlogTitle = "人生若只如初见" });
            blogNews.Add(new BlogNew { BlogID = 2, BlogTitle = "何事秋风悲画扇" });
            blogNews.Add(new BlogNew { BlogID=3,BlogTitle="最喜欢纳兰性德"});

            dataGridView1.DataBindings.Add("DataSource", this, "blogNews", false, DataSourceUpdateMode.OnPropertyChanged);
 }
复制代码

这样绑定完毕以后,在界面上,我们可以非常自豪的看到自己新加的三条数据。当然,这个没有什么奇怪的。需要注意的是,在这里,我们设置了DataSourceUpdateMode.OnPropertyChanged,也就是说,当数据源的改变的时候,数据将重新加载,那么为了测试数据能不能够自动重新加载(不需要重新绑定数据源),我们来做个测试,界面上加一个按钮,用来添加一条新的记录:

复制代码
private void button3_Click(object sender, EventArgs e)
        {
            //在这里向DataGridView中插入一行
            var data = dataGridView1.DataSource as List<BlogNew>;
            data.Add(new BlogNew { BlogID = 4, BlogTitle = "取次花丛懒回顾,半缘修道半缘君" });

            foreach(BlogNew blogNew in dataGridView1.DataSource as List<BlogNew>)
            {
                /***********
                 * 当我们心插入一条BlogID记录为4的数据的时候,在界面上可以看出dataGridView1的dataSource已经被更新,
                 * 但是界面上依旧显示为BlogID为1,2,3三条数据,很奇怪
                 * *********************/
                MessageBox.Show(blogNew.BlogID + "--" + blogNew.BlogTitle); 
            }
        }
复制代码

好了,这里我添加了一条新的数据,并且没有进行数据重新绑定,点击按钮,但是悲剧发生了,界面上没有任何新的记录出现,怎么回事?但是通过foreach循环,我们发现第四条记录明明被添加到数据源中了呀?怎么回事呢?其实我这里也没有搞明白到底为什么,还请大家指教,要解决这个问题,我们应该利用BindingList<T>泛型类来替换掉List<T>泛型类:

复制代码
 public BindingList<BlogNew> blogNewsRegardUI {get;set; }  //应用于DataGridView界面UI更新 

 private void mainFrm_Load(object sender, EventArgs e)
 {
       blogNewsRegardUI = new BindingList<BlogNew>();
       blogNewsRegardUI.Add(new BlogNew { BlogID = 11, BlogTitle = "僵卧孤村不自哀" });
       blogNewsRegardUI.Add(new BlogNew { BlogID = 12, BlogTitle = "尚思为国戍轮台" });
       blogNewsRegardUI.Add(new BlogNew { BlogID = 13, BlogTitle = "夜阑卧听风吹雨" });

       dataGridView2.DataBindings.Add("DataSource", this, "blogNewsRegardUI", false, DataSourceUpdateMode.OnPropertyChanged);

  }

        
  private void button4_Click(object sender, EventArgs e)
  {
       /*这里主要用来解决DataGridView1界面不更新的问题,其实原因在于使用了List<BlogNew>,这里我们采用BindList<BlogNew>
        *通过测试,我们发现,只要数据源改变,界面就可以自动的进行更新了,很是方便,不需要重新绑定
         */
        var dataRegardUI = dataGridView2.DataSource as BindingList<BlogNew>;
        dataRegardUI.Add(new BlogNew { BlogID = 20, BlogTitle = "竹外桃花三两枝,春江水暖鸭先知" });
  }
复制代码

然后当我们再点击添加按钮的时候,我们发现,虽然我们没有重新绑定数据源(只是数据源有所改变),就导致界面正确的添加进去数据了。

呵呵,希望有用,谢谢,下面附上截图和全部代码:

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class mainFrm : Form
    {
        public mainFrm()
        {
            InitializeComponent();
        }

        MyDataSource mydatasource = new MyDataSource();  //应用于第二种方式
        
        public int Num { get; set; }  //应用于第三种方式

        public List<BlogNew> blogNews { get; set; }  //应用于第四种方式

        public BindingList<BlogNew> blogNewsRegardUI {get;set; }  //应用于DataGridView界面UI更新 

        private void mainFrm_Load(object sender, EventArgs e)
        {
            #region 测试一
            /************************************************
             * 第一个值:要绑定到TextBox的什么地方
             * 第二个值:数据源是什么
             * 第三个值:应该取数据源的什么属性
             * 第四个值:是否开启数据格式化
             * 第五个值:在什么时候启用数据源绑定
             * *********************************************/
            textBox1.DataBindings.Add("Text", trackBar1, "Value", false, DataSourceUpdateMode.OnPropertyChanged);
            #endregion

            #region 测试二
            /*********************************************
             * 这个主要就是通过一个外部的类,当做数据源
             * *********************************************/
            
            mydatasource.Myvalue = "这是个测试";
            textBox2.DataBindings.Add("Text",mydatasource,"Myvalue",false,DataSourceUpdateMode.OnPropertyChanged);
            #endregion

            #region 测试三
            /*****************************************
             *这个主要就是通过本身拥有的属性,当做数据源
             ****************************************/
            Num = 5;
            textBox3.DataBindings.Add("Text",this,"Num", false,DataSourceUpdateMode.OnPropertyChanged);
            #endregion

            #region 测试四 : List<T>
            blogNews = new List<BlogNew>();
            blogNews.Add(new BlogNew { BlogID = 1, BlogTitle = "人生若只如初见" });
            blogNews.Add(new BlogNew { BlogID = 2, BlogTitle = "何事秋风悲画扇" });
            blogNews.Add(new BlogNew { BlogID=3,BlogTitle="最喜欢纳兰性德"});

            dataGridView1.DataBindings.Add("DataSource", this, "blogNews", false, DataSourceUpdateMode.OnPropertyChanged);

            #endregion

            #region 测试五 : BindingList<T>
            blogNewsRegardUI = new BindingList<BlogNew>();
            blogNewsRegardUI.Add(new BlogNew { BlogID = 11, BlogTitle = "僵卧孤村不自哀" });
            blogNewsRegardUI.Add(new BlogNew { BlogID = 12, BlogTitle = "尚思为国戍轮台" });
            blogNewsRegardUI.Add(new BlogNew { BlogID = 13, BlogTitle = "夜阑卧听风吹雨" });

            dataGridView2.DataBindings.Add("DataSource", this, "blogNewsRegardUI", false, DataSourceUpdateMode.OnPropertyChanged);

            #endregion
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //从这里可以看出,改变了TextBox2中的值,这里的值也改变了,原因是因为类属于引用类型
            MessageBox.Show(mydatasource.Myvalue);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //从这里可以看出,改变了TextBox3中的值,这里的值也改变了,
            //原因是Num被当做了当前窗体的一个属性(窗体本身就是一个类),也属于引用类型
            MessageBox.Show(Num.ToString());
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //在这里向DataGridView中插入一行
            var data = dataGridView1.DataSource as List<BlogNew>;
            data.Add(new BlogNew { BlogID = 4, BlogTitle = "取次花丛懒回顾,半缘修道半缘君" });

            foreach(BlogNew blogNew in dataGridView1.DataSource as List<BlogNew>)
            {
                /***********
                 * 当我们心插入一条BlogID记录为4的数据的时候,在界面上可以看出dataGridView1的dataSource已经被更新,
                 * 但是界面上依旧显示为BlogID为1,2,3三条数据,很奇怪
                 * *********************/
                MessageBox.Show(blogNew.BlogID + "--" + blogNew.BlogTitle); 
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            /*这里主要用来解决DataGridView1界面不更新的问题,其实原因在于使用了List<BlogNew>,这里我们采用BindList<BlogNew>
             *通过测试,我们发现,只要数据源改变,界面就可以自动的进行更新了,很是方便,不需要重新绑定
             */
            var dataRegardUI = dataGridView2.DataSource as BindingList<BlogNew>;
            dataRegardUI.Add(new BlogNew { BlogID = 20, BlogTitle = "竹外桃花三两枝,春江水暖鸭先知" });
        }
    }

    public class MyDataSource
    {
        public string Myvalue { get; set; }
    }

    public class BlogNew
    {
        public int BlogID { get; set; }
        public string BlogTitle { get; set; }
    }
}   
复制代码

截图如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值