WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】

一、问题:DataGridView在显示数据的时候,如何快捷的修改列名(数据库字段变成有意义的列名)?

1、数据库中的表:

WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】

; 2、UI上的dataGridView要显示的列名

WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】

3、解决方法:

一、数据装载完毕后,修改dataGridView的列名【如何修改?自行搜索】——此法较笨
二、dataGridView数据绑定前,修改数据源(DataTable)的列名,如何修改,在Select sql的时候修改

  • 最初的sql 语句
SELECT id,
    username,
    nickname,
    password,
    sex,
    email,
    phone,
    remark
FROM user;
  • 改进的sql语句,以及抓取的table
    WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】

二、问题:sqlite在select时,如何获取行号?

1、想要的效果cnt作为行号,在分页的时候用来计算

WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】
其它数据库里面有一个函数row_number(),sqlite里面没有,所以只能曲线救国

; 2、代码

select id, (select count(*) from user b  where a.id >= b.id) as cnt  from user a

三、dataGridView如何分页

1、数据绑定

var table = DB.GetUserTable();
var pageInfo = GetSpecifiedPage(1,30,ref table);
bindingSource.DataSource = pageInfo.table;
dataGridView1.DataSource = bindingSource;

数据流示意图

WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】

2、分页的思路

  • 分页显示的流程
    WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】
  • 分页的实现
    比如,table里面有91行数据,每页显示30行,那么总计可以分成4页——30 + 30 + 30 + 1
    分页的情况:

页码 (第x页)行号起始值行号结束值1029230593608949090

比如现在要显示第2页的数据,那么直接把第 30_到第 59_行的数据重新装到一个新表里,然后把这个新表设置成dataGridView的数据源就行。
用Linq,Skip属于前面页码的rows,然后Take30行即可

  • 代码实现

        public static (bool success,DataTable table,string info) GetSpecifiedPage(int pageIndex,int rowsNumInOnePage,ref DataTable table)
        {
            (bool success, DataTable table, string info) rtn ;

            float t = (float)table.Rows.Count / (float)rowsNumInOnePage;
            var totalPages = (int)(Math.Ceiling(t));

            if(pageIndex < 1 || pageIndex > totalPages)
            {
                rtn = (false, new DataTable(), "给定的页码越界");
            }
            else
            {

                var skipRows = (pageIndex - 1) * rowsNumInOnePage;
                var takeRows = rowsNumInOnePage;
                var rows = table.AsEnumerable().Skip(skipRows).Take(takeRows).ToList();
                var rtnTable = new DataTable();

                rtnTable = table.Clone();
                rows.ForEach(r => rtnTable.ImportRow(r));
                rtn = (true,rtnTable,"");
            }
            return rtn;
        }
  • 把一个DataTable(表1)的rows添加(add)到另一个DataTable(表2)的时候,表2需要和表1有相同的表结构,不然会报错: 该行已经属于另一个表
  • 处理方案(1):把总表 拷贝(copy)给临时表
    官方说:Copy()的意思——把表的结构和表的数据都复制一份。DataTable.Copy() returns a DataTable with the structure and data of the DataTable.

那么Copy()后,你需要把临时表clear(),再重新装数据

var rtnTable = new DataTable();
rtnTable = table.Copy();
rtnTable.Clear();
rows.ForEach(r => rtnTable.ImportRow(r));
  • 处理方案(2):把总表 克隆(clone)给临时表
    官方说:Clone()的意思——只取表的结构不要表的数据。//Unlike Copy(), DataTable.Clone() only returns the structure of the DataTable, not the rows or data of the DataTable.

所以Clone()后,临时表不需要clear()

var rtnTable = new DataTable();
rtnTable = table.Clone();
rows.ForEach(r => rtnTable.ImportRow(r));

Original: https://blog.csdn.net/dzj2021/article/details/126946348
Author: dzj2021
Title: WinForm中DataGridView分页的实现【DataTable.rows.add()报错:该行已经属于另一个表】

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/816009/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球