我们如何在winform中的datagridview中进行分页

时间:2010-05-13 09:44:51

标签: c# winforms datagridview custom-controls pagination

我想在窗口表单的datagridview中显示每页10条记录,用户必须单击下一步按钮才能显示下10条记录。是否在DataGridview中有一些属性,或者我是否需要创建自定义控件。

我需要做些什么才能实现这一目标。

8 个答案:

答案 0 :(得分:31)

这是一个简单的工作示例,其中a BindingNavigator GUI控件使用a BindingSource反对 通过将其DataSource设置为IListSource的自定义子类来标识分页符。 (感谢this answer 关键的想法。)当用户点击“下一页”按钮时,BindingNavigator会激活bindingSource1_CurrentChanged,您的代码可以获取所需的记录。说明:

  1. 创建Windows窗体应用程序
  2. 在表单上拖动BindingNavigator,DataGridView和BindingSource
  3. 使用以下代码替换Form1.cs:
  4. using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    namespace PagedDataGridView
    {
        public partial class Form1 : Form
        {
            private const int totalRecords = 43;
            private const int pageSize = 10;
    
            public Form1()
            {
                InitializeComponent();
                dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { DataPropertyName = "Index" });
                bindingNavigator1.BindingSource = bindingSource1;
                bindingSource1.CurrentChanged += new System.EventHandler(bindingSource1_CurrentChanged);
                bindingSource1.DataSource = new PageOffsetList();
            }
    
            private void bindingSource1_CurrentChanged(object sender, EventArgs e)
            {
                // The desired page has changed, so fetch the page of records using the "Current" offset 
                int offset = (int)bindingSource1.Current;
                var records = new List<Record>();
                for (int i = offset; i < offset + pageSize && i < totalRecords; i++)
                    records.Add(new Record { Index = i });
                dataGridView1.DataSource = records;
            }
    
            class Record
            {
                public int Index { get; set; }
            }
    
            class PageOffsetList : System.ComponentModel.IListSource
            {
                public bool ContainsListCollection { get; protected set; }
    
                public System.Collections.IList GetList()
                {
                    // Return a list of page offsets based on "totalRecords" and "pageSize"
                    var pageOffsets = new List<int>();
                    for (int offset = 0; offset < totalRecords; offset += pageSize)
                        pageOffsets.Add(offset);
                    return pageOffsets;
                }
            }
        }
    }
    

答案 1 :(得分:8)

这是我的解决方案:我花了将近一年的时间才找到它并为此感到自豪

public class SuperGrid : DataGridView
    {
        public int PageSize
        {
            get
            {
                return _pageSize;
            }
            set
            {
                _pageSize = value;
            }
        }
        public int _pageSize = 10;
        BindingSource bs = new BindingSource();
        BindingList<DataTable> tables = new BindingList<DataTable>();
        public void SetPagedDataSource(DataTable dataTable, BindingNavigator bnav)
        {
            DataTable dt = null;
            int counter = 1;
            foreach (DataRow dr in dataTable.Rows)
            {
                if (counter == 1)
                {
                    dt = dataTable.Clone();
                    tables.Add(dt);
                }
                dt.Rows.Add(dr.ItemArray);
                if (PageSize < ++counter  )
                {
                    counter = 1;
                }
            }
            bnav.BindingSource = bs;
            bs.DataSource = tables;
            bs.PositionChanged += bs_PositionChanged;
            bs_PositionChanged(bs, EventArgs.Empty);
        }
        void bs_PositionChanged(object sender, EventArgs e)
        {
            this.DataSource = tables[bs.Position];
        }
    }

如何使用它?将上面的代码添加到项目中,将Supergrid和一个bindingnavigator控件拖到你的win表单中。

 superGrid1.PageSize = 5;
 DataTable dt = DataProvider.ExecuteDt("select * from test order by col");
  superGrid1.SetPagedDataSource(dt, bindingNavigator1);

你得到一个带有数据绑定的分页Datagridview而没有太多hastle /

答案 2 :(得分:1)

解决此问题的另一种方法:

public class PagedGrid : DataGridView
    {
        Paging pg;
        SQLQuery s;
        public void SetPagedDataSource(  SQLQuery s, BindingNavigator bnav)
        {
            this.s = s;
            int count = DataProvider.ExecuteCount(s.CountQuery);
            pg = new Paging(count, 5);
            bnav.BindingSource = pg.BindingSource;
            pg.BindingSource.PositionChanged += new EventHandler(bs_PositionChanged);
            //first page
            string q = s.GetPagingQuery(pg.GetStartRowNum(1), pg.GetEndRowNum(1), true);
            DataTable dt = DataProvider.ExecuteDt(q);
            DataSource = dt;
        }

        void bs_PositionChanged(object sender, EventArgs e)
        {
            int pos = ((BindingSource)sender).Position + 1;
            string q = s.GetPagingQuery(pg.GetStartRowNum(pos), pg.GetEndRowNum(pos), false);
            DataTable dt = DataProvider.ExecuteDt(q);
            DataSource = dt;
        }

        public void UpdateData()
        {
            DataTable dt = (DataTable)DataSource;
            using (SqlConnection con = new SqlConnection(DataProvider.conStr))
            {
                con.Open();
                SqlDataAdapter da = new SqlDataAdapter(s.CompleteQuery, con);
                SqlCommandBuilder cb = new SqlCommandBuilder(da);
                da.UpdateCommand = cb.GetUpdateCommand();
                da.InsertCommand = cb.GetInsertCommand();
                da.DeleteCommand = cb.GetDeleteCommand();
                da.Update(dt);
            }
            MessageBox.Show("The changes are committed to database!");
        }
    }


  /// <summary>
    /// Gives functionality of next page , etc for paging.
    /// </summary>
    public class Paging
    {
        public int _totalSize = 0;
        private int _pageSize = 0;

        public int TotalSize
        {
            get
            {
                return _totalSize;
            }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentException();
                }
                _totalSize = value;
            }
        }

        public int PageSize
        {
            get
            {
                return _pageSize;
            }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentException();
                }
                _pageSize = value;
            }
        }

        public Paging(int totalSize, int pageSize)
        {
            this.TotalSize = totalSize;
            this.PageSize = pageSize;
        }

        public int GetStartRowNum(int PageNum)
        {
            if (PageNum < 1)
            {
                throw new Exception("Page number starts at 1");
            }
            if (PageNum > GetPageCount())
            {
                throw new Exception("Page number starts at " + GetPageCount().ToString());
            }
            return 1 + ((PageNum - 1) * _pageSize);
        }

        public int GetEndRowNum(int PageNum)
        {
            if (PageNum < 1)
            {
                throw new Exception("Page number starts at 1");
            }
            if (PageNum > GetPageCount())
            {
                throw new Exception("Page number starts at " + GetPageCount().ToString());
            }
            return _pageSize + ((PageNum - 1) * _pageSize);
        }

        public int GetPageCount()
        {
            return (int)Math.Ceiling(TotalSize / (decimal)PageSize);
        }

        public bool IsFirstPage(int PageNum)
        {
            if (PageNum == 1)
            {
                return true;
            }
            return false;
        }

        public bool IsLastPage(int PageNum)
        {
            if (PageNum == GetPageCount())
            {
                return true;
            }
            return false;
        }
        private int _currentPage = 1;
        public int CurrentPage
        {
            get
            {
                return _currentPage;
            }
            set
            {
                _currentPage = value;
            }
        }
        public int NextPage
        {
            get
            {
                if (CurrentPage + 1 <= GetPageCount())
                {
                    _currentPage = _currentPage + 1;
                }
                return _currentPage;
            }
        }

        public int PreviousPage
        {
            get
            {
                if (_currentPage - 1 >= 1)
                {
                    _currentPage = _currentPage - 1;
                }
                return _currentPage;
            }
        }
        private BindingSource _bindingSource = null;
        public BindingSource BindingSource
        {
            get
            {
                if (_bindingSource == null)
                {
                    _bindingSource = new BindingSource();
                    List<int> test = new List<int>();
                    for (int i = 0; i < GetPageCount(); i++)
                    {
                        test.Add(i);
                    }
                    _bindingSource.DataSource = test;
                }
                return _bindingSource;
            }

        }
    }


    /// <summary>
    /// Query Helper of Paging
    /// </summary>
    public class SQLQuery
    {

        private string IDColumn = "";
        private string WherePart = " 1=1 ";
        private string FromPart = "";
        private string SelectPart = "";

        public SQLQuery(string SelectPart, string FromPart, string WherePart, string IDColumn)
        {
            this.IDColumn = IDColumn;
            this.WherePart = WherePart;
            this.FromPart = FromPart;
            this.SelectPart = SelectPart;

        }

        public string CompleteQuery
        {
            get
            {
                if (WherePart.Trim().Length > 0)
                {
                    return string.Format("Select {0} from {1} where {2} ", SelectPart, FromPart, WherePart);
                }
                else
                {
                    return string.Format("Select {0} from {1} ", SelectPart, FromPart);
                }
            }
        }

        public string CountQuery
        {
            get
            {
                if (WherePart.Trim().Length > 0)
                {
                    return string.Format("Select count(*) from {0} where {1} ", FromPart, WherePart);
                }
                else
                {
                    return string.Format("Select count(*) from {0} ", FromPart);

                }
            }
        }



        public string GetPagingQuery(int fromrow, int torow, bool isSerial)
        {
            fromrow--;
            if (isSerial)
            {
                return string.Format("{0} where {1} >= {2} and {1} <= {3}", CompleteQuery, IDColumn, fromrow, torow);
            }
            else
            {
                string select1 = "";
                string select2 = "";
                if (WherePart.Trim().Length > 0)
                {
                    select1 = string.Format("Select top {3} {0} from {1} where {2} ", SelectPart, FromPart, WherePart, torow.ToString());
                    select2 = string.Format("Select top {3} {0} from {1} where {2} ", SelectPart, FromPart, WherePart, fromrow.ToString());
                }
                else
                {
                    select1 = string.Format("Select top {2} {0} from {1} ", SelectPart, FromPart, torow.ToString());
                    select2 = string.Format("Select top {2} {0} from {1} ", SelectPart, FromPart, fromrow.ToString());
                }
                if (fromrow <= 1)
                {
                    return select1;
                }
                else
                {
                    return string.Format("{0} except {1} ", select1, select2);
                }

            }
        }


    }

使用它:

 private void Form1_Load(object sender, EventArgs e)
        {
            SQLQuery s = new SQLQuery("*", "table", "", "id");
            pagedGrid1.SetPagedDataSource(s, bindingNavigator1);
        }

注意:此处不包含DataPrivier类,它是一个从任何源返回数据表的简单类。

答案 3 :(得分:1)

试试这个, 此代码适用于OleDb,但也适用于SqlServer连接。 dt(DataTable)对象用选定的页面行填充,假设页面以1(不是0)开头

public DataTable getData(string sql, int pgNo, int totalRows) 
{
DataTable dt = null;
        using (OleDbConnection conn = new OleDbConnection(connStr))
        {
            try
            {
                DataSet ds;
                conn.Open();
                ds = new DataSet();
                OleDbDataAdapter adapter = new OleDbDataAdapter(sql, conn);
                adapter.Fill(ds, (pgNo-1)*totalRows, totalRows, "Table");
                conn.Close();
                dt = ds.Tables[0];
            }
            catch (Exception ex)
            {if (conn != null) conn.Dispose();}
return dt;
}

答案 4 :(得分:0)

使用RadGridView for WinForms进行分页仿真是可能的,尤其是如果我们充分利用LINQ。这种方法还给我们带来了另一个优势-客户绩效。数据处理(过滤,排序和分页)显然是由SQL Server完成的,该服务器针对此类情况进行了完全优化,而不是针对应用程序进行了优化。客户端一次只处理和显示一页,而不是全部百万条记录。在这里,我不使用RadGridView的虚拟模式-这是更高级的博客文章的主题。 该链接对我有帮助:paging-with-radgridview https://www.telerik.com/blogs/emulating-paging-with-radgridview-for-winforms-and-linq-with-1-million-records

,代码为:

private void BindGrid()
{
 this.radGridView1.GridElement.BeginUpdate();

 IQueryable queryable = new DataClasses1DataContext().MyTables.AsQueryable();

 if (!String.IsNullOrEmpty(where))
    {
        queryable = queryable.Where(where);
    }

 if (!String.IsNullOrEmpty(orderBy))
    {
        queryable = queryable.OrderBy(orderBy);
    }

    radGridView1.DataSource = queryable.Skip(currentPageIndex * pageSize).Take(pageSize);

 this.radGridView1.GridElement.EndUpdate(true);

    EnableDisablePager();
}

答案 5 :(得分:0)

使用C#和VB.Net在Windows窗体(WinForms)应用程序中实现分页DataGridView,这是另一种解决方案: https://www.aspsnippets.com/Articles/Implement-Paging-DataGridView-in-Windows-Forms-WinForms-Application-using-C-and-VBNet.aspx

在本文中,将说明如何使用C#和VB.Net在Windows窗体(WinForms)应用程序中实现分页DataGridView。 Windows窗体(WinForms)应用程序中的DataGridView控件不具有分页功能,因此需要实现使用存储过程的自定义分页。 存储过程接受PageIndex和PageSize作为输入参数,以便获取所需页面索引的记录。为了在前端填充分页器,需要使用RecordCount Output参数获取表中的记录总数。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
CREATE PROCEDURE [dbo].[GetCustomersPageWise]
      @PageIndex INT = 1
      ,@PageSize INT = 10
      ,@RecordCount INT OUTPUT
AS
BEGIN
      SET NOCOUNT ON;
      SELECT ROW_NUMBER() OVER
      (
            ORDER BY [CustomerID] ASC
      )AS RowNumber
            ,[CustomerID]
            ,[ContactName]
            ,[Country]
       INTO #Results
      FROM [Customers]

      SELECT @RecordCount = COUNT(*)
      FROM #Results

      SELECT [CustomerID]
            ,[ContactName]
            ,[Country] 
      FROM #Results
      WHERE RowNumber BETWEEN(@PageIndex -1) * @PageSize + 1 AND(((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1

      DROP TABLE #Results
END

最初,PageSize的值设置为5,PageIndex设置为1。RecordCount Output参数和PageIndex的值传递给PopulatePager方法(稍后讨论)。

C#
//Set the Page Size.
int PageSize = 5;
private void Form1_Load(object sender, EventArgs e)
{
    this.BindGrid(1);
}

private void BindGrid(int pageIndex)
{
    string constring = @"Data Source=.\SQL2005;Initial Catalog=Northwind;Integrated Security=true";
    using (SqlConnection con = new SqlConnection(constring))
    {
        using (SqlCommand cmd = new SqlCommand("GetCustomersPageWise", con))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@PageIndex", pageIndex);
            cmd.Parameters.AddWithValue("@PageSize", PageSize);
            cmd.Parameters.Add("@RecordCount", SqlDbType.Int, 4);
            cmd.Parameters["@RecordCount"].Direction = ParameterDirection.Output;
            con.Open();
            DataTable dt = new DataTable();
            dt.Load(cmd.ExecuteReader());
            dataGridView1.DataSource = dt;
            con.Close();
            int recordCount = Convert.ToInt32(cmd.Parameters["@RecordCount"].Value);
            this.PopulatePager(recordCount, pageIndex);
        }
    }
}

为每个动态Button分配一个click事件处理程序,当单击Button时,其Name的值作为PageIndex参数传递给BindGrid函数,该函数使用新的记录集填充DataGridView。

C#
private void PopulatePager(int recordCount, int currentPage)
{
    List<Page> pages = new List<Page>();
    int startIndex, endIndex;
    int pagerSpan = 5;

    //Calculate the Start and End Index of pages to be displayed.
    double dblPageCount = (double)((decimal)recordCount / Convert.ToDecimal(PageSize));
    int pageCount = (int)Math.Ceiling(dblPageCount);
    startIndex = currentPage > 1 && currentPage + pagerSpan - 1 < pagerSpan ? currentPage : 1;
    endIndex = pageCount > pagerSpan ? pagerSpan : pageCount;
    if (currentPage > pagerSpan % 2)
    {
        if (currentPage == 2)
        {
            endIndex = 5;
        }
        else
        {
            endIndex = currentPage + 2;
        }
    }
    else
    {
        endIndex = (pagerSpan - currentPage) + 1;
    }

    if (endIndex - (pagerSpan - 1) > startIndex)
    {
        startIndex = endIndex - (pagerSpan - 1);
    }

    if (endIndex > pageCount)
    {
        endIndex = pageCount;
        startIndex = ((endIndex - pagerSpan) + 1) > 0 ? (endIndex - pagerSpan) + 1 : 1;
    }

    //Add the First Page Button.
    if (currentPage > 1)
    {
        pages.Add(new Page { Text = "First", Value = "1" });
    }

    //Add the Previous Button.
    if (currentPage > 1)
    {
        pages.Add(new Page { Text = "<<", Value = (currentPage - 1).ToString() });
    }

    for (int i = startIndex; i <= endIndex; i++)
    {
        pages.Add(new Page { Text = i.ToString(), Value = i.ToString(), Selected = i == currentPage });
    }

    //Add the Next Button.
    if (currentPage < pageCount)
    {
        pages.Add(new Page { Text = ">>", Value = (currentPage + 1).ToString() });
    }

    //Add the Last Button.
    if (currentPage != pageCount)
    {
        pages.Add(new Page { Text = "Last", Value = pageCount.ToString() });
    }

    //Clear existing Pager Buttons.
    pnlPager.Controls.Clear();

    //Loop and add Buttons for Pager.
    int count = 0;
    foreach (Page page in pages)
    {
        Button btnPage = new Button();
        btnPage.Location = new System.Drawing.Point(38 * count, 5);
        btnPage.Size = new System.Drawing.Size(35, 20);
        btnPage.Name = page.Value;
        btnPage.Text = page.Text;
        btnPage.Enabled = !page.Selected;
        btnPage.Click += new System.EventHandler(this.Page_Click);
        pnlPager.Controls.Add(btnPage);
        count++;
    }
}

private void Page_Click(object sender, EventArgs e)
{
    Button btnPager = (sender as Button);
    this.BindGrid(int.Parse(btnPager.Name));
}

public class Page
{
    public string Text { get; set; }
    public string Value { get; set; }
    public bool Selected { get; set; }
}

答案 6 :(得分:0)

我在datagridview上进行了手动分页。希望对您有帮助

private void btnBack_Click(object sender, EventArgs e)
    {
        int a = int.Parse(lblmin.Text);
        int b = int.Parse(lblmax.Text);
        int c = a - 100;
        int d = b - 100;

        if (lblmin.Text != "1")
        {
            String name = "Main";
            String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
                            "C:\\BBISDatabase\\Data.xlsx" +
                            ";Extended Properties='Excel 8.0;HDR=YES;';";

            OleDbConnection con = new OleDbConnection(constr);
            OleDbCommand oconn = new OleDbCommand("Select * From [" + name + "$] where IDs between " + c.ToString() + " and " + d.ToString() + "", con);
            con.Open();

            OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
            DataTable data = new DataTable();
            sda.Fill(data);
            dgMain.DataSource = data;
            lblcount.Text = c.ToString();
            lblmax.Text = d.ToString();
        }
        else
        {
            btnBack.Visible = false;
        }
    }

    private void btnNext_Click(object sender, EventArgs e)
    {

        int a = int.Parse(lblmin.Text);
        int b = int.Parse(lblmax.Text);
        int c = b + 1;
        int d = b + 100;

        String name = "Main";
        String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
                        "C:\\BBISDatabase\\Data.xlsx" +
                        ";Extended Properties='Excel 8.0;HDR=YES;';";

        OleDbConnection con = new OleDbConnection(constr);
        OleDbCommand oconn = new OleDbCommand("Select * From [" + name + "$] where IDs between "+c.ToString()+" and "+d.ToString()+"", con);
        con.Open();

        OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
        DataTable data = new DataTable();
        sda.Fill(data);
        dgMain.DataSource = data;
        lblmin.Text = c.ToString();
        lblmax.Text = d.ToString();
        btnBack.Visible = true;

    }

然后我将这段代码放在form_load()上:

lblmin.Text = "1";

答案 7 :(得分:0)

我的回答迟了十年,我无法开始解释原因。但是我认为重要的是我要提供一些东西。 :D

我喜欢以最简单的方式解决问题,到目前为止,这是我使用的最简单的方式。如果有任何问题,很高兴对其进行修复。

using System;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Drawing;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        SqlDataAdapter pagingAdapter;
        DataSet pagingDS;
        int scrollVal; // This defines how many more data sets there are to load
        int rowsPerPage = 10; // This defines the total number of rows to show

        public Form1()
        {
            InitializeComponent();
            scrollVal = 0;
        }

        private void BtnShowresults_Click(object sender, EventArgs e)
        {
            string connectionString = "Data Source=.;Initial Catalog=pubs;Integrated Security=True";
            string sql = "SELECT * FROM Authors";
            SqlConnection connection = new SqlConnection(connectionString);
            pagingAdapter = new SqlDataAdapter(sql, connection);
            pagingDS = new DataSet();
            connection.Open();

            //This part will get the total number of records from the query
            pagingAdapter.Fill(dataSetProjects);
            DataTable dataTable = pagingDS.Tables[0];
            int rowCount = Convert.ToInt32(dataTable.Rows.Count);
            this.btnShowresults.Tag = rowCount; // We set it to the button tag

            pagingAdapter.Fill(pagingDS, scrollVal, rowsPerPage, "Authors_table");
            connection.Close();
            dataGridView1.DataSource = pagingDS;
            dataGridView1.DataMember = "Authors_table";
        }

        private void btnPrevious_Click(object sender, EventArgs e)
        {
            if (scrollVal < = 0)
            {
                scrollVal = 0;
            } else
            {
                scrollVal -= rowsPerPage;
            }
            pagingDS.Clear();
            pagingAdapter.Fill(pagingDS, scrollVal, rowsPerPage, "authors_table");
        }

        private void BtnNext_Click(object sender, EventArgs e)
        {
            Button btnShowresults = (Button)pnSearch.Controls["btnShowresults"];
            int resCount = Convert.ToInt32(btnShowresults.Tag);
            if (scrollVal <= resCount)
            {
                scrollVal = rowsPerPage;
            } else 
            {
                scrollVal = rowsPerPage;
            }
            pagingDS.Clear();
            pagingAdapter.Fill(pagingDS, scrollVal, rowsPerPage, "authors_table");
        }
    }
}

此代码位于http://csharp.net-informations.com/datagridview/csharp-datagridview-paging.htm上。它有一些我需要修复的错误。认为这是一个清理后的版本。