DataGridView动态加载部分数据防止卡顿[源码]

DataGridView是我们显示表格数据最常用的控件, 非常好用,功能强大。但是当数据量特别大时(不管是行还是列,行的影响会小一些,列的影响特别明显)直接绑定数据会占用很久的时间,并且不能响应用户的操作而造成卡顿。所以我们就需要用到动态加载,加载部分数据,当用户滚动到边界时再加载后面的一部分数据,我们控制每次加载的行或者列的数量来保证加载速度。我们以动态加载列为示例,下面示例建立了一个1000列的table,每次加载100列供当前DataGridView显示。我们已经尝试过创建10000列的table,用此示例动态显示没有任何问题。如果直接绑定要等20分钟左右才能加载出来。

完整代码如下:form上面有两个textbox用来指定行和列的数量,一个button用来create Source table. 一个DataGridView且AutoGenerateColumns=false

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DataTable MasterTable = null;//Source table 500 row x 1000 col
        int MaskSize = 50; //Load MaskSize*2 Columns every time
        int MaskStart = 0; //Display columns start index
        int MaskEnd = 0;//Display columns end index

        //To Create Source Table, column and Row counts defined by ColCnt and RowCnt from textbox on form
        private void createTableButton_Click(object sender, EventArgs e)
        {
            int ColCnt = int.Parse(textBox1.Text.Trim());//1000
            int RowCnt = int.Parse(textBox2.Text.Trim());//500
            //create master source table
            MasterTable = new DataTable();
            for (int c = 0; c < ColCnt; c++)
            {
                MasterTable.Columns.Add("C" + c.ToString(), typeof(float));
            }
            for(int r=0;r< RowCnt; r++)
            {
                DataRow dr = MasterTable.NewRow();
                for (int c = 0; c < ColCnt; c++)
                {
                    dr["C" + c.ToString()] = r * 1.0 + c*0.01;
                }
                MasterTable.Rows.Add(dr);
            }

            //initialzie datagriview by loading 0 ~ 100 columns
            int LoadStart = MaskStart;
            int LoadEnd = MaskSize*1;
            if (LoadEnd >= MasterTable.Columns.Count - 1)
                LoadEnd = MasterTable.Columns.Count - 1;
            //Dynamically create dataGridview columns
            for (int i = LoadStart; i <= LoadEnd; i++)
            {
                DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn();
                dgvc.DataPropertyName = MasterTable.Columns[i].ColumnName;
                dgvc.HeaderText = MasterTable.Columns[i].ColumnName;
                dataGridView1.Columns.Add(dgvc);
                MaskEnd = i;
            }
            //Load subset from SourceTable
            dataGridView1.DataSource = MasterTable;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Type t = dataGridView1.GetType();
            PropertyInfo pi = t.GetProperty("HorizontalScrollBar", BindingFlags.Instance | BindingFlags.NonPublic);
            ScrollBar s = null;
            if (pi != null)
            {
                s = pi.GetValue(dataGridView1, null) as ScrollBar;
            }
            if (s != null)
            {
                s.Scroll += new ScrollEventHandler(s_Scroll);
            }
            dataGridView1.AutoGenerateColumns = false;
        }

        //define horiontal dedegate functoin
        void s_Scroll(object sender, ScrollEventArgs e)
        {
            HScrollBar HSBar = (HScrollBar)sender;
            int HBarWid = HSBar.Width;
            int OldValue = e.OldValue;
            int NewValue = e.NewValue;
            int MaxVal = HSBar.Maximum;
            int ScrollVal = HSBar.Value;
            StatusLabel1.Text ="Old Value:"+ OldValue.ToString() + ", New Value:"+NewValue.ToString()+ ", Scroll Value:" + ScrollVal.ToString()+", Bar Width:"+ HBarWid.ToString() + ", Max:" + MaxVal.ToString() +", Max_85:"+(0.85 * MaxVal).ToString();

            //scroll to end (right) and load next 100 columns
            if (NewValue > OldValue && ScrollVal + HBarWid >= MaxVal)
            {
                LoadDataToGridView(true);
            }
            //scroll to beginning (left) and load previous 100 columns
            else if (NewValue < OldValue && ScrollVal <= 0)
            {
                LoadDataToGridView(false);
            }

        }

        bool DataReload = false;//flag to indicate data just reloaded
        void LoadDataToGridView(bool LoadRight)
        {
            //Load right, and not reach end of MasterSourceTable
            if(LoadRight && MaskEnd != MasterTable.Columns.Count -1)
            {
                //clear all dataGridView columns
                dataGridView1.Columns.Clear();

                //define current loading start
                int LoadEnd = MaskEnd + MaskSize;
                if(LoadEnd> MasterTable.Columns.Count - 1)
                    LoadEnd = MasterTable.Columns.Count - 1;
                MaskEnd = LoadEnd;
                //define current loading end
                int LoadStart = MaskEnd - 2 * MaskSize;
                if (LoadStart < 0)
                    LoadStart = 0;
                MaskStart = LoadStart;

                //create new dataGridColumns to bind current subset of MasterDataTable
                for (int i = LoadStart; i <= LoadEnd; i++)
                {
                    DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn();
                    dgvc.DataPropertyName = MasterTable.Columns[i].ColumnName;
                    dgvc.HeaderText = MasterTable.Columns[i].ColumnName;
                    dataGridView1.Columns.Add(dgvc);
                    MaskEnd = i;
                }

                dataGridView1.DataSource = MasterTable;
                DataReload = true;
                //Invalidate dataGridView to trigger re-paint, we can only set scroll bar to center in Paint() event
                dataGridView1.Invalidate();
                StatusLabel1.Text = "Data columns [" + LoadStart.ToString() + " ~ " + LoadEnd.ToString() + "] loaded.";
            }

            //Load Left, not reached beginning of MasterSourceTable
            if (!LoadRight && MaskStart != 0)
            {
                dataGridView1.Columns.Clear();

                int LoadStart = MaskStart - MaskSize;
                if (LoadStart < 0)
                    LoadStart = 0;
                MaskStart = LoadStart;

                int LoadEnd = LoadStart + 2 * MaskSize;
                if (LoadEnd > MasterTable.Columns.Count - 1)
                    LoadEnd = MasterTable.Columns.Count - 1;
                MaskEnd = LoadEnd;

                for (int i = LoadStart; i <= LoadEnd; i++)
                {
                    DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn();
                    dgvc.DataPropertyName = MasterTable.Columns[i].ColumnName;
                    dgvc.HeaderText = MasterTable.Columns[i].ColumnName;
                    dataGridView1.Columns.Add(dgvc);
                    MaskEnd = i;
                }

                dataGridView1.DataSource = MasterTable;
                DataReload = true;
                dataGridView1.Invalidate();
                StatusLabel1.Text = "Data columns [" + LoadStart.ToString() + " ~ " + LoadEnd.ToString() + "] loaded.";
            }  
        }

        private void dataGridView1_Paint(object sender, PaintEventArgs e)
        {
            if(DataReload)
            {
                //if data just re-loaded, set scrollBar to center
                DataReload = false;
                dataGridView1.FirstDisplayedScrollingColumnIndex = dataGridView1.Columns.Count / 2;
            }
        }
    }

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在 WinForms 的 DataGridView动态加载并显示图片,您可以按照以下步骤进行操作: 1. 在 DataGridView 中添加一个列来显示图片。可以使用 DataGridViewImageColumn 类型的列来显示图片。 2. 在代码中动态加载图片,并将其赋值给 DataGridView 中对应的单元格。 以下是一个示例,展示了如何动态加载并显示图片: ```csharp // 创建一个 DataGridViewImageColumn 列来显示图片 DataGridViewImageColumn imageColumn = new DataGridViewImageColumn(); imageColumn.HeaderText = "图片"; imageColumn.ImageLayout = DataGridViewImageCellLayout.Zoom; // 设置图片布局方式 // 将列添加到 DataGridView 控件中 dataGridView1.Columns.Add(imageColumn); // 加载图片并设置到单元格中 string imagePath = "path_to_image.png"; // 图片的路径 Image image = Image.FromFile(imagePath); // 加载图片 int rowIndex = 0; // 要设置图片的行索引 // 创建一个 DataGridViewImageCell,并将图片赋值给它 DataGridViewImageCell imageCell = new DataGridViewImageCell(); imageCell.Value = image; // 将 DataGridViewImageCell 设置到指定的单元格中 dataGridView1.Rows[rowIndex].Cells["图片"].Value = imageCell; ``` 在上述示例中,我们首先创建了一个 DataGridViewImageColumn 列,并设置其显示图片的布局方式为 Zoom。然后将该列添加到 DataGridView 控件中。 接下来,我们加载要显示的图片,并将其赋值给 DataGridView 中的指定单元格。通过创建一个 DataGridViewImageCell 对象,并将图片赋值给它,然后将该 DataGridViewImageCell 设置到指定的单元格中。 请注意,上述示例中的 "图片" 是 DataGridView 中图片列的名称,请根据实际情况修改。同时,也可以在代码中使用循环来动态加载多张图片到多个单元格中。 这样,您就可以在 WinForms 的 DataGridView动态加载并显示图片了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值