ウィンドウフォームのデータグリッドビューでページごとに10レコードを表示したいので、ユーザーは次のボタンをクリックして次の10レコードを表示する必要があります。 DataGridviewにいくつかのプロパティがありますか、カスタムコントロールを作成する必要がありますか?.
これを達成するために私がする必要があること。
BindingNavigator GUIコントロールが IListSource のカスタムサブクラスにDataSourceを設定することにより、 BindingSource オブジェクトを使用して改ページを識別する単純な作業例を示します。 =。 (重要なアイデアについて この回答 に感謝します。)ユーザーが「次のページ」ボタンをクリックすると、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年かかり、この1つを誇りに思っています
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);
そして、あなたは多くの手間をかけずにデータバインディングでページ化されたデータグリッドビューを取得します/
この問題の別のアプローチ:
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クラスはここには含まれていません。これは、任意のソースからデータテーブルを返す単純なクラスです。
これを試してください。このコードはOleDb用ですが、SqlServer接続でも機能します。ページが1(0ではない)で始まると仮定して、dt(DataTable)オブジェクトは選択されたページ行で埋められます。
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;
}