2010-05-13 72 views
13

Quiero mostrar 10 registros por página en una vista de tabla de datos en un formulario de ventana y el usuario debe hacer clic en el botón siguiente para mostrar los 10 registros siguientes. ¿Hay alguna propiedad en DataGridview o necesito crear un control personalizado?¿Cómo podemos hacer paginación en datagridview en winform

Lo que necesito hacer para lograr esto.

+0

este enlace puede ayudar http://programcall.com/9/dotnet/datagridview-paging- .net-winforms-cs.aspx – Mou

Respuesta

27

Aquí es un simple ejemplo de trabajo, donde un control BindingNavigator GUI utiliza un BindingSource objeto a identificar saltos de página, estableciendo su fuente de datos a una subclase personalizada de IListSource. (Gracias a this answer por la idea clave.) Cuando el usuario hace clic en el botón "página siguiente", BindingNavigator activa bindingSource1_CurrentChanged y su código puede recuperar los registros deseados. Instrucciones:

  1. Crear una aplicación Windows Forms
  2. Arrastre en la forma de un BindingNavigator, un DataGridView, y una BindingSource
  3. Reemplazar Form1.cs con el código siguiente:
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: ¡Hola! Muchas gracias por el código. Es realmente útil. Solo un problema. Tengo código como: var transactionLogCount = TransactionLogManager.GetTransactionLogCount(); El comando anterior da cuenta total. var transactionLogList = new List (); transactionLogList.AddRange (TransactionLogManager.GetAllTransactionLog (int StartIndex, int EndIndex);!. ahora cómo hacer paginación cuando tengo que añadir todo el tiempo en el bucle for –

6

Aquí está mi solución: Me tomó casi un año encontrarlo y estoy orgulloso de este

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

¿Cómo usarlo? Agregue el código anterior a su proyecto, arrastre la superred y un control bindingnavigator a su formulario de ganar.

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

y se obtiene un Datagridview paginado con encuadernación sin mucho buscabamos datos/

+0

Grandes acaba de crear un control personalizado para usarlo muchas veces . Un par de cosas que debes cambiar. 1.- Al comienzo de SetPagedDataSource debe inicializar las variables bs y tablas: bs = new BindingSource(); tables = new BindingList (); 2.- Verifique si (bs.Position> 0) antes de la acción dentro de bs_PositionChanged(). Felicidades! –

+0

cómo se modifican las columnas, suponiendo que desea agregar columnas como ver, editar y eliminar –

1

Otro enfoque para este 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: El La clase DataPrivier no está incluida aquí, es una clase simple que devuelve datatable desde cualquier fuente.

1

Pruebe esto, este código es para OleDb, pero también funciona para conexiones SqlServer. El dt (DataTable) objeto está lleno de filas de página seleccionados, suponiendo que la página comienza con 1 (no 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; 
} 
Cuestiones relacionadas