首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Winforms DataGridView in VirtualMode什么时候调用AutoResizeColumn?

Winforms DataGridView in VirtualMode什么时候调用AutoResizeColumn?
EN

Stack Overflow用户
提问于 2012-03-04 06:58:41
回答 2查看 2.7K关注 0票数 2

我已经在我的表单上实现了一个DataGridView,并成功地实现了VirtualMode。这从本地缓存中检索单元数据,在填充网格/分页等时,所有数据似乎都正常工作。我处理DataGridView.CellValueNeeded事件来填充单元格。

在DataGridView上,AutoSizeColumnsMode属性设置为DataGridViewAutoSizeColumnsMode.DisplayedCells。我注意到在使用VirtualMode时,DataGridView在填充单元格后似乎不尊重AutoSizeColumnsMode。我检查了这篇文章,但没有找到解决方案。

我最终想要做的是不依赖AutoSizeColumnsMode属性,而是在某个地方调用.AutoResizeColumn()方法来调整大小,所以我最初自动调整列的大小,然后允许用户调整大小。

我尝试了以下几种方法,结果有限或没有成功:

  1. DataGridView.AutoSizeColumnsMode设置为.None。然后在我的.CellValueNeeded处理程序中 私有dataGridView_CellValueNeeded(对象发送方,DataGridViewCellValueEventArgs e) { // .从缓存DataGridViewAutoSizeColumnMode.DisplayedCells);(e.ColumnIndex,e.ColumnIndex)中获取单元格值 这会抛出一个StackOverFlowException,大概是因为它多次引发.CellValueNeeded
  2. 除了在.CellFormatting事件处理程序中,尝试了完全相同的事情。得到了同样的StackOverFlowException
  3. 尝试使用和不使用DataGridView.SuspendLayout/ResumeLayout: 私有dataGridView_CellValueNeeded(对象发送方,DataGridViewCellValueEventArgs e) { // .从缓存DataGridViewAutoSizeColumnMode.DisplayedCells);-= dataGridView_CellValueNeeded;dataGridView.AutoResizeColumn(e.ColumnIndex,dataGridView.CellValueNeeded += dataGridView_CellValueNeeded;})获取单元格值。 这给了所有的空白单元格,所以没有用。
  4. 这个实际上有点工作,因为我不明白的原因: 私有dataGridView_CellValueNeeded(对象发送方,DataGridViewCellValueEventArgs e) { // .从缓存DataGridViewAutoSizeColumnsMode.DisplayedCells;= dataGridView.AutoSizeColumnsMode }获取单元格值 它正确地调整了列的大小,但是必须对每个所需的单元格值重复调用它似乎很奇怪。而且,我不能马上将它设置为.None,否则它将再次StackOverFlowException。因此,我不能允许用户调整列的大小。
  5. 本文中提到的从我的.CellValueNeeded处理程序调用.CellValueNeeded也会抛出StackOverFlowException

那么,是否有可能在.AutoResizeColumn()溢出之前不会引发.CellValueNeeded的地方调用它呢?由于#4似乎具有执行自动大小函数的能力,所以我似乎也可以从某个地方手动调用它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-05 02:32:43

我认为这可能是解决问题的办法,但我仍有兴趣听取其他人的意见。

我继续查看DataGridView引发的其他一些事件,并发现了.RowPostPaint事件。我创建了以下处理程序:

代码语言:javascript
复制
private void dataGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    if (dataGridView.AllowUserToResizeColumns) //So not to run unnecessarily
    {
        return;
    }
    var lastIndex = dataGridView.Rows.GetLastRow(DataGridViewElementStates.Displayed);
    if (e.RowIndex == lastIndex) //Only do on the last displayed row
    {
        dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
        dataGridView.AllowUserToResizeColumns = true;  // User has control from here on
    }
}

这样就可以在初始数据加载时自动调整列的大小,然后允许用户从那里重新调整大小。它只做了一次,所以比每个所需的单元格值都要好得多。我必须在初始数据加载之前设置dataGridView.AllowUserToResizeColumns = false

这似乎符合要求。用户将在初始加载时看到很好的适合列,并且可以从那里调整,而且我的大部分数据都是行到行的可比长度,因此在大多数情况下不应该截断或浪费空间。

票数 2
EN

Stack Overflow用户

发布于 2017-03-26 05:56:15

由于您对其他人必须说的内容感兴趣,所以我已经为如何使用虚拟数据网格自动调整列大小提供了一种稍微不同的方法。

在显示事件之后放置初始的AutoResizeColumns调用,以便初始化和显示窗体和子组件。此外,通过连接用于调整大小的DataGridView Scroll事件(而不是RowPostPaint ),这应该会稍微提高一些效率,因为该事件的触发频率较低,而且我认为它与您引用的MSDN引用一起进行得很好:

代码语言:javascript
复制
using System.Collections.Generic;
using System.Windows.Forms;

namespace DataGridViewTest
{
    public partial class DataGridViewForm : Form
    {
        private List<string> dataSource;

        public DataGridViewForm()
        {
            InitializeComponent();

            // Enable VirtualMode for dataGridView1
            dataGridView1.VirtualMode = true;

            // Wire CellValueNeeded event handler
            dataGridView1.CellValueNeeded += DataGridView1_CellValueNeeded;

            // Wire Scroll event handler
            dataGridView1.Scroll += DataGridView1_Scroll;

            // Wire form Shown event handler
            this.Shown += DataGridViewForm_Shown;
        }

        private void DataGridViewForm_Shown(object sender, System.EventArgs e)
        {
            // Populate dataGridView1 here to avoid perception of a long form startup time
            populateDataGridView();

            // Resize columns after the form is initialized and displayed on screen,
            // otherwise calling this method won't actually have an effect on column sizes
            dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
        }

        private void DataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            // Set the triggering cell's value to the corresponding value from dataSource
            e.Value = dataSource[e.RowIndex];
        }

        private void DataGridView1_Scroll(object sender, ScrollEventArgs e)
        {
            // Resize columns again, but only if a vertical scroll just happened
            if (e.ScrollOrientation == ScrollOrientation.VerticalScroll)
            {
                dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
            }
        }

        private void populateDataGridView()
        {
            fetchIntoDataSource();

            associateDataSourceToDataGridView();
        }

        private void fetchIntoDataSource()
        {
            dataSource = new List<string>();

            // Insert a test string into dataSource many times
            for (int i = 0; i < 1000; i++)
            {
                dataSource.Add("test string");
            }
        }

        private void associateDataSourceToDataGridView()
        {
            // Synchronize dataGridView1.RowCount to dataSource.Count
            // This is necessary for the CellValueNeeded event to fire
            dataGridView1.RowCount = dataSource.Count;
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9553022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档