利用winform中DataGridView的显示较大数量的的数据

在大数据量的情况下,想要通过DataGridView直接显示出来.明显不是一个很好的办法,甚至有可能用在可视化界面的资源高于需要显示的数据很多.

一种可行的方案就是使用虚表,虚表的工作原理也比较简单,概括起来就是动态的将数据加载
到一个行数很少的DataGridview中.

如果只是想展示数据而不需要修改数据,只需要将DataGridview的VirtualMode设置为True,添加好列对象,然后添加CellValueNeeded委托就行了,如下:

this.dataGridView1.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);

通过这个委托的名字大致就可以知道,应该是需要在这里为某个需要数据的Cell填充数据.这个数据的来源应该是后台的数据源.同时,通过事件的参数中可以得到需要加载数据的行和列的下标,在这里只需要将需要提交的数据赋值给e.Value就行了.(需要注意的是:在初始化的时候应该为DataGridView.RowCount设置一个值,这个值是需要显示的数据的列的总数.同时尽量不要在加载数据的委托里边向控制台输出信息或者其他耗时的操作)

到这里,如果只是需要简单的显示数据而不用编辑数据,一个方便快捷的虚表就完成了.但是如果数据量超过一定的限度,这个标的加载速度比较慢.同时根据使用情况来看,在初始化的时候会全部加载数据,然后在显示出来的时候又会全部加载一次数据,鼠标扫过一行也会调用一次数据加载的委托.这个没有怎么去深究过.

总结:使用起来比较方便快捷,不过这个主要是为可编辑的大数据设计的.因此如果仅仅只是想展示大数据量的话,这个解决方案还不是很好,

下面是微软MSDN的示例源码和链接:


using System.IO;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System;

public class VirtualModeDemo : Form
{
    DataGridView dataGridView1 = new DataGridView();

    public VirtualModeDemo()
        : base()
    {
        Text = "DataGridView virtual-mode demo (cell-level commit scope)";
        dataGridView1.NewRowNeeded +=
            new DataGridViewRowEventHandler(dataGridView1_NewRowNeeded);
        dataGridView1.RowsAdded +=
            new DataGridViewRowsAddedEventHandler(dataGridView1_RowsAdded);
        dataGridView1.CellValidating +=
            new DataGridViewCellValidatingEventHandler(dataGridView1_CellValidating);
        dataGridView1.CellValueNeeded +=
            new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);
        dataGridView1.CellValuePushed +=
            new DataGridViewCellValueEventHandler(dataGridView1_CellValuePushed);

        Controls.Add(dataGridView1);
        dataGridView1.VirtualMode = true;
        dataGridView1.AllowUserToDeleteRows = false;
        dataGridView1.Columns.Add("Numbers", "Positive Numbers");
        dataGridView1.Rows.AddCopies(0, initialSize);
    }

    bool newRowNeeded;
    private void dataGridView1_NewRowNeeded(object sender,
        DataGridViewRowEventArgs e)
    {
        newRowNeeded = true;
    }

    const int initialSize = 5000000;
    int numberOfRows = initialSize;

    private void dataGridView1_RowsAdded(object sender,
         DataGridViewRowsAddedEventArgs e)
    {
        if (newRowNeeded)
        {
            newRowNeeded = false;
            numberOfRows = numberOfRows + 1;
        }
    }

    #region "data store maintance"
    const int initialValue = -1;

    private void dataGridView1_CellValueNeeded(object sender,
        DataGridViewCellValueEventArgs e)
    {
        if (store.ContainsKey(e.RowIndex))
        {
            // Use the store if the e value has been modified 
            // and stored.            
            e.Value = store[e.RowIndex];
        }
        else if (newRowNeeded && e.RowIndex == numberOfRows)
        {
            if (dataGridView1.IsCurrentCellInEditMode)
            {
                e.Value = initialValue;
            }
            else
            {
                // Show a blank value if the cursor is just resting
                // on the last row.
                e.Value = String.Empty;
            }
        }
        else
        {
            e.Value = e.RowIndex;
        }
    }

    private void dataGridView1_CellValuePushed(object sender,
        DataGridViewCellValueEventArgs e)
    {
        store.Add(e.RowIndex, int.Parse(e.Value.ToString()));
    }
    #endregion

    private Dictionary<int, int> store = new Dictionary<int, int>();

    private void dataGridView1_CellValidating(object sender,
        DataGridViewCellValidatingEventArgs e)
    {
        dataGridView1.Rows[e.RowIndex].ErrorText = "";
        int newInteger;

        // Don't try to validate the 'new row' until finished 
        // editing since there
        // is not any point in validating its initial value.
        if (dataGridView1.Rows[e.RowIndex].IsNewRow) { return; }
        if (!int.TryParse(e.FormattedValue.ToString(),
            out newInteger) || newInteger < 0)
        {
            e.Cancel = true;
            dataGridView1.Rows[e.RowIndex].ErrorText = "the value must be a non-negative integer";
        }
    }

    [STAThreadAttribute()]
    public static void Main()
    {
        Application.Run(new VirtualModeDemo());
    }
}


微软MSDN示例源码


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
WinForm ,可以通过双向数据绑定来实现 DataGridView 控件与数据源之间的数据同步。当数据源的值发生改变时,DataGridView 控件会自动刷新显示;当用户在 DataGridView 修改了数据时,数据源的值也会自动更新。 以下是实现双向数据绑定的步骤: 1. 定义一个实体类,来表示要绑定的数据对象,该实体类的属性应该和 DataGridView 的列一一对应。 ```C# public class Person { public string Name { get; set; } public int Age { get; set; } public string Gender { get; set; } } ``` 2. 在 Form 创建 DataGridView 控件,并设置其 DataSource 属性为 BindingSource 的实例。 ```C# BindingSource personSource = new BindingSource(); personSource.DataSource = typeof(Person); dataGridView1.DataSource = personSource; ``` 3. 创建一个 Person 对象的实例,并将其绑定到 BindingSource 。 ```C# Person person = new Person() { Name = "Tom", Age = 20, Gender = "Male" }; personSource.Add(person); ``` 4. 在需要进行双向数据绑定的 DataGridView 列上,设置其 DataPropertyName 属性为 Person 对象的属性名。 ```C# dataGridView1.Columns["Name"].DataPropertyName = "Name"; dataGridView1.Columns["Age"].DataPropertyName = "Age"; dataGridView1.Columns["Gender"].DataPropertyName = "Gender"; ``` 5. 如果需要在 DataGridView 修改数据,可以通过 DataGridView 的 CurrentCellDirtyStateChanged 事件和 CellValueChanged 事件来实现数据源的更新。 ```C# private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) { if (dataGridView1.IsCurrentCellDirty) { dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); } } private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex >= 0 && e.ColumnIndex >= 0) { Person person = personSource.Current as Person; personSource.EndEdit(); } } ``` 以上就是在 WinForm 实现双向数据绑定的基本步骤。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值