2010-05-13 7 views
13

Voglio mostrare 10 record per pagina in una vista datagrid su un modulo di finestra e l'utente deve fare clic sul pulsante Avanti per mostrare i prossimi 10 record. C'è qualche proprietà in DataGridview o devo creare un controllo personalizzato.Come possiamo fare l'impaginazione in datagridview in winform

Cosa devo fare per raggiungere questo obiettivo.

+0

questo collegamento può aiutare http://programcall.com/9/dotnet/datagridview-paging- .net-winforms-cs.aspx – Mou

risposta

27

Ecco un semplice esempio di lavoro, in cui utilizza un controllo BindingNavigator GUI un BindingSource oggetto identificare le interruzioni di pagina, impostando la sua DataSource a una sottoclasse personalizzata di IListSource. (Grazie a this answer per l'idea chiave.) Quando l'utente fa clic sul pulsante "pagina successiva", BindingNavigator attiva bindingSource1_CurrentChanged e il codice può recuperare i record desiderati. Istruzioni:

  1. Creare un'applicazione Windows Form
  2. Trascinare nel form un BindingNavigator, un DataGridView, e un BindingSource
  3. Sostituire Form1.cs con il seguente codice:
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; 
      } 
     } 
    } 
} 
+0

@Rick Mohr: Ciao! Grazie mille per il codice. È davvero utile Solo un problema Ho il codice come: var transactionLogCount = TransactionLogManager.GetTransactionLogCount(); Il comando precedente fornisce il conteggio totale. var transactionLogList = new List (); transactionLogList.AddRange (TransactionLogManager.GetAllTransactionLog (int StartIndex, int EndIndex);.! ora come fare il paging quando ho bisogno di aggiungere tutto il tempo nel ciclo for –

6

Ecco la mia soluzione: mi ci è voluto quasi un anno per trovarlo e orgoglioso di questo

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]; 
     } 
    } 

Come si usa? Aggiungi il codice sopra al tuo progetto, trascina il Supergrid e un controllo bindingnavigator sul tuo modulo di vittoria.

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

E si ottiene un Datagridview paging con associazione dati senza molta hastle/

+0

Grandi appena creato un controllo personalizzato da utilizzare molte volte Un paio di cose che dovresti cambiare 1.- All'inizio di SetPagedDataSource dovresti inizializzare le variabili bs e tables: bs = new BindingSource(); tables = new BindingList (); 2.- Verifica se (bs.Position> 0) prima dell'azione all'interno di bs_PositionChanged(). Congratulazioni! –

+0

come si modificano le colonne, assumendo che si vogliano aggiungere colonne come vista, modifica ed eliminazione –

1

un altro approccio per questo problema:

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); 
       } 

      } 
     } 


    } 

usarlo:

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

Nota: La La classe DataPrivier non è inclusa qui, è una classe semplice che ritorna datatable da qualsiasi fonte.

1

Prova questo, questo codice è per OleDb, ma funziona anche per le connessioni SqlServer. Il dt (DataTable) oggetto è riempito con righe pagine selezionati, assumendo che pagina inizia con 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; 
} 
Problemi correlati