BindingList详解

发布时间:2023-05-19

从BindingList中读取数据

BindingList是.NET Framework中的一个强类型数据结构,它继承自IList接口,添加了一些便捷的事件和方法,可以方便地将数据和控件进行绑定,实现数据绑定。 BindingList的常用操作包括添加、删除和修改数据等。下面是一个从BindingList中读取数据的示例:

BindingList<Student> studentList = new BindingList<Student>(); //创建一个BindingList
studentList.Add(new Student() { Name = "Tom", Age = 18, Gender = "Male" }); //添加数据
foreach(Student student in studentList) //遍历数据
{
    MessageBox.Show(student.Name + ":" + student.Age + "岁," + student.Gender); //弹出消息框显示数据
}

BindingList清空操作之后报错

如果在对BindingList进行Clear操作后,尝试从中读取数据,可能会抛出“没有项可以与此位置关联”异常。这是由于Clear方法会删除BindingList中的所有元素,但不会将元素的引用也一并删除,导致数据读取时出现错误。解决方法是对BindingList重新进行实例化,如下所示:

BindingList<Student> studentList = new BindingList<Student>(); //创建一个BindingList
studentList.Clear(); //清空操作
studentList = new BindingList<Student>(); //重新实例化

BindingList字段重复

如果使用BindingList进行数据绑定时,遇到字段重复的情况,则需要将字段名指定为“别名”,以避免冲突。例如,如果两个字段均命名为“Name”,则可以将其中一个字段命名为“Name2”,如下所示:

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }
    public string Name2 { get { return this.Name; } set { this.Name = value; } } //指定别名
}

BindingList的foreach方法不见了

使用foreach方法遍历BindingList是一个常见的操作,但是在某些情况下,可能会出现未定义方法的错误提示。这是由于BindingList并没有直接实现IEnumerable<T>接口,而是通过IEnumerable接口进行实现。解决方法是使用cast转换,将BindingList强制转换为IEnumerable<T>类型,如下所示:

BindingList<Student> studentList = new BindingList<Student>(); //创建一个BindingList
foreach (Student student in (IEnumerable<Student>)studentList) //通过cast转换实现遍历
{
    Console.WriteLine(student.Name + ":" + student.Age + "岁," + student.Gender); //控制台输出数据
}

BindingList大数据量绑定

使用BindingList进行大数据量的数据绑定可能会影响程序性能,导致资源浪费,甚至出现程序崩溃等问题。为了解决这个问题,可以使用虚拟模式(Virtual Mode)进行数据绑定。虚拟模式是指只将当前可见的数据加载到内存中,当用户滚动时动态加载前后的数据,以确保程序的高效和流畅。下面是一个使用虚拟模式的示例:

public class VirtualListDemo : Form
{
    private DataGridView dataGridView1;
    private BindingList<Student> studentList = new BindingList<Student>();
    public VirtualListDemo()
    {
        dataGridView1.VirtualMode = true; //启用虚拟模式
        dataGridView1.VirtualRowCount = 1000; //设置虚拟行数
        dataGridView1.CellValueNeeded += DataGridView1_CellValueNeeded; //绑定CellValueNeeded事件
    }
    private void DataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        if (studentList.Count > e.RowIndex) //判断是否超出BindingList的数据范围
        {
            Student student = studentList[e.RowIndex];
            switch (dataGridView1.Columns[e.ColumnIndex].Name) //根据列名读取数据
            {
                case "Name":
                    e.Value = student.Name;
                    break;
                case "Age":
                    e.Value = student.Age;
                    break;
                case "Gender":
                    e.Value = student.Gender;
                    break;
            }
        }
    }
}

BindingList可以和树控件绑定吗?

可以使用BindingList和TreeView控件进行数据绑定。使用BindingList绑定TreeView的方法是将具有父子关系的节点转换为树形结构,使用递归算法进行处理。下面是一个绑定TreeView的示例:

public class TreeNodeDemo : Form
{
    private TreeView treeView1;
    private BindingList<TreeNode> nodeList = new BindingList<TreeNode>();
    public TreeNodeDemo()
    {
        treeView1.NodeMouseClick += TreeView1_NodeMouseClick; //绑定NodeMouseClick事件
        BindTree(); //绑定树形结构数据
    }
    private void BindTree()
    {
        nodeList.Add(new TreeNode("父节点1")
        {
            Nodes =
            {
                new TreeNode("子节点1"),
                new TreeNode("子节点2")
            }
        }); //添加数据
        nodeList.Add(new TreeNode("父节点2")); //添加数据
        treeView1.Nodes.Clear();
        foreach (TreeNode node in nodeList)
        {
            treeView1.Nodes.Add(node); //添加节点
        }
    }
    private void TreeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
    {
        MessageBox.Show(e.Node.Text); //弹出消息框显示节点内容
    }
}

BindingList出现索引0没有对象

如果在对BindingList进行操作时出现“索引0没有对象”的错误,可能是由于绑定的数据源为空导致的。解决方法是在使用BindingList之前,先进行判断数据源是否为空,如下所示:

BindingList<Student> studentList = new BindingList<Student>(); //创建一个BindingList
if(dataTable != null && dataTable.Rows.Count > 0) //判断数据源是否为空
{
    foreach(DataRow row in dataTable.Rows)
    {
        studentList.Add(new Student() { Name = row["Name"], Age = row["Age"], Gender = row["Gender"] }); //添加数据
    }
}

BindingList和Dapper

Dapper是一种轻量级的ORM(对象关系映射)工具,可以方便地实现对数据库的操作,而BindingList是实现数据绑定的一种常用工具。将Dapper和BindingList结合使用,可以更加方便地对数据库进行操作,并实现自动数据绑定的效果。下面是一个使用Dapper和BindingList的示例:

public class DapperDemo : Form
{
    private BindingList<Product> productList = new BindingList<Product>();
    public DapperDemo()
    {
        dataGridView1.DataSource = productList; //将DataGridView和BindingList进行绑定
        LoadData(); //加载数据
    }
    private void LoadData()
    {
        string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            productList = conn.Query<Product>("SELECT * FROM Products").ToBindingList(); //使用Dapper查询数据,将结果转换为BindingList
            dataGridView1.DataSource = productList; //更新DataGridView的数据源
        }
    }
}