我想在窗口表单的datagridview中显示每页10条记录,用户必须单击下一步按钮才能显示下10条记录。是否在DataGridview中有一些属性,或者我是否需要创建自定义控件。
我需要做些什么才能实现这一目标。
答案 0 :(得分:31)
这是一个简单的工作示例,其中a
BindingNavigator GUI控件使用a
BindingSource反对
通过将其DataSource设置为IListSource的自定义子类来标识分页符。
(感谢this answer
关键的想法。)当用户点击“下一页”按钮时,BindingNavigator会激活bindingSource1_CurrentChanged
,您的代码可以获取所需的记录。说明:
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上。它有一些我需要修复的错误。认为这是一个清理后的版本。