web-dev-qa-db-ja.com

winformのdatagridviewでページネーションを行う方法

ウィンドウフォームのデータグリッドビューでページごとに10レコードを表示したいので、ユーザーは次のボタンをクリックして次の10レコードを表示する必要があります。 DataGridviewにいくつかのプロパティがありますか、カスタムコントロールを作成する必要がありますか?.

これを達成するために私がする必要があること。

20
Shantanu Gupta

BindingNavigator GUIコントロールが IListSource のカスタムサブクラスにDataSourceを設定することにより、 BindingSource オブジェクトを使用して改ページを識別する単純な作業例を示します。 =。 (重要なアイデアについて この回答 に感謝します。)ユーザーが「次のページ」ボタンをクリックすると、BindingNavigatorがbindingSource1_CurrentChangedそして、コードは目的のレコードを取得できます。手順:

  1. Windowsフォームアプリケーションを作成する
  2. BindingNavigator、DataGridView、およびBindingSourceをフォームにドラッグします
  3. Form1.csを次のコードに置き換えます。
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;
            }
        }
    }
}
32
Rick Mohr

ここに私の解決策があります:それを見つけるのに約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);

そして、あなたは多くの手間をかけずにデータバインディングでページ化されたデータグリッドビューを取得します/

9
Thunder

この問題の別のアプローチ:

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クラスはここには含まれていません。これは、任意のソースからデータテーブルを返す単純なクラスです。

1
Thunder

これを試してください。このコードは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;
}
1
Begench