Je veux afficher 10 enregistrements par page dans un datagridview sur un formulaire de fenêtre et l'utilisateur doit cliquer sur le bouton Suivant pour afficher les 10 prochains enregistrements. Est-ce une propriété dans DataGridview ou dois-je créer un contrôle personnalisé?.
Ce que je dois faire pour y parvenir.
Voici un exemple de travail simple, dans lequel a BindingNavigator GUI control utilise a BindingSource object avec Identifier les sauts de page, en définissant sa source de données dans une sous-classe personnalisée de IListSource .(Merci à cette réponse pour L'idée clé.) Lorsque l'utilisateur clique sur le bouton "page suivante", le BindingNavigator déclenche bindingSource1_CurrentChanged
et votre code peut extraire les enregistrements souhaités. Instructions:
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;
}
}
}
}
Voici ma solution: il m'a fallu presque un an pour le trouver et fier de celui-ci
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];
}
}
Comment l'utiliser? Ajoutez le code ci-dessus à votre projet, faites glisser le contrôle Supergrid et un contrôle bindingnavigator sur votre formulaire gagnant.
superGrid1.PageSize = 5;
DataTable dt = DataProvider.ExecuteDt("select * from test order by col");
superGrid1.SetPagedDataSource(dt, bindingNavigator1);
Et vous obtenez une Datagridview paginée avec une liaison de données sans trop de hâte /
Une autre approche pour ce problème:
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);
}
}
}
}
en l'utilisant:
private void Form1_Load(object sender, EventArgs e)
{
SQLQuery s = new SQLQuery("*", "table", "", "id");
pagedGrid1.SetPagedDataSource(s, bindingNavigator1);
}
Remarque: La classe DataPrivier n'est pas incluse ici. Il s'agit d'une classe simple qui renvoie des données pouvant être datées de n'importe quelle source.
Essayez ceci, Ce code est pour OleDb, mais fonctionne également pour les connexions SqlServer . L'objet dt (DataTable) est rempli avec les lignes de page sélectionnées, en supposant que la page commence par 1 (non 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;
}