Почему CellValueNedded изначально вызывается для всех элементов списка массивов - PullRequest
0 голосов
/ 03 мая 2020

Я реализовал код для datagridview в virtualmode. Мой магазин содержит 42 товара в array. Может кто-нибудь объяснить мне, почему сначала он вызывает CellValueNeeded 42 раза, а затем 13 раз? Я понимаю 13 раз, потому что это предметы, которые можно показывать на сетке в режиме реального времени, но я не понимаю, что 42 раза раньше. Если бы у меня было миллион элементов в массиве CellValueNeeded, его также первоначально назвали бы миллионами раз, что не имеет смысла для меня, поскольку эти записи не требуются в этот момент, а 13, и, с моей точки зрения, это не то, для чего предназначен виртуальный режим.

Код был взят из ссылки MSDN

Полный код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DataGridViewVirtual
{
    public partial class Form1 : Form
    {

        // Declare an ArrayList to serve as the data store.
        private System.Collections.ArrayList customers =
            new System.Collections.ArrayList();

        // Declare a Customer object to store data for a row being edited.
        private Customer customerInEdit;

        // Declare a variable to store the index of a row being edited.
        // A value of -1 indicates that there is no row currently in edit.
        private int rowInEdit = -1;

        // Declare a variable to indicate the commit scope.
        // Set this value to false to use cell-level commit scope.
        private bool rowScopeCommit = true;

        public Form1()
        {
            InitializeComponent();
            this.dataGridView1.Dock = DockStyle.None;
            this.Controls.Add(this.dataGridView1);
            this.Load += new EventHandler(Form1_Load);
            this.Text = "DataGridView virtual-mode demo (row-level commit scope)";
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Enable virtual mode.
            this.dataGridView1.VirtualMode = true;

            // Connect the virtual-mode events to event handlers.
            this.dataGridView1.CellValueNeeded += new
                DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);
            this.dataGridView1.CellValuePushed += new
                DataGridViewCellValueEventHandler(dataGridView1_CellValuePushed);
            this.dataGridView1.NewRowNeeded += new
                DataGridViewRowEventHandler(dataGridView1_NewRowNeeded);
            this.dataGridView1.RowValidated += new
                DataGridViewCellEventHandler(dataGridView1_RowValidated);
            this.dataGridView1.RowDirtyStateNeeded += new
                QuestionEventHandler(dataGridView1_RowDirtyStateNeeded);
            this.dataGridView1.CancelRowEdit += new
                QuestionEventHandler(dataGridView1_CancelRowEdit);
            this.dataGridView1.UserDeletingRow += new
                DataGridViewRowCancelEventHandler(dataGridView1_UserDeletingRow);

            // Add columns to the DataGridView.
            DataGridViewTextBoxColumn companyNameColumn = new
                DataGridViewTextBoxColumn();
            companyNameColumn.HeaderText = "Company Name";
            companyNameColumn.Name = "Company Name";
            DataGridViewTextBoxColumn contactNameColumn = new
                DataGridViewTextBoxColumn();
            contactNameColumn.HeaderText = "Contact Name";
            contactNameColumn.Name = "Contact Name";
            this.dataGridView1.Columns.Add(companyNameColumn);
            this.dataGridView1.Columns.Add(contactNameColumn);
            this.dataGridView1.AutoSizeColumnsMode =
                DataGridViewAutoSizeColumnsMode.AllCells;

            // Add some sample entries to the data store.
            this.customers.Add(new Customer(
                "1", "1"));
            this.customers.Add(new Customer(
                "2", "2"));
            this.customers.Add(new Customer(
                "3", "3"));
            this.customers.Add(new Customer(
                "4", "4"));
            this.customers.Add(new Customer(
                "5", "5"));
            this.customers.Add(new Customer(
                "6", "6"));
            this.customers.Add(new Customer(
                "7", "7"));
            this.customers.Add(new Customer(
                "8", "8"));
            this.customers.Add(new Customer(
                "9", "9"));
            this.customers.Add(new Customer(
                "10", "10"));
            this.customers.Add(new Customer(
                "11", "11"));
            this.customers.Add(new Customer(
                "12", "12"));
            this.customers.Add(new Customer(
                "13", "13"));
            this.customers.Add(new Customer(
                "14", "14"));
            this.customers.Add(new Customer(
                "15", "15"));
            this.customers.Add(new Customer(
                "16", "16"));
            this.customers.Add(new Customer(
                "17", "17"));
            this.customers.Add(new Customer(
                "18", "18"));
            this.customers.Add(new Customer(
                "19", "19"));
            this.customers.Add(new Customer(
                "20", "20"));
            this.customers.Add(new Customer(
                "21", "21"));
            this.customers.Add(new Customer(
                "22", "22"));
            this.customers.Add(new Customer(
                "23", "23"));
            this.customers.Add(new Customer(
                "24", "24"));
            this.customers.Add(new Customer(
                "25", "25"));
            this.customers.Add(new Customer(
                "26", "26"));
            this.customers.Add(new Customer(
                "27", "27"));
            this.customers.Add(new Customer(
                "28", "28"));
            this.customers.Add(new Customer(
                "29", "29"));
            this.customers.Add(new Customer(
                "30", "30"));
            this.customers.Add(new Customer(
                "31", "31"));
            this.customers.Add(new Customer(
                "32", "32"));
            this.customers.Add(new Customer(
                "33", "33"));
            this.customers.Add(new Customer(
                "34", "34"));
            this.customers.Add(new Customer(
                "35", "35"));
            this.customers.Add(new Customer(
                "36", "36"));
            this.customers.Add(new Customer(
                "37", "37"));
            this.customers.Add(new Customer(
                "38", "38"));
            this.customers.Add(new Customer(
                "39", "39"));
            this.customers.Add(new Customer(
                "40", "40"));
            this.customers.Add(new Customer(
                "41", "42"));


            // Set the row count, including the row for new records.
            this.dataGridView1.RowCount = 42;
        }

        private void dataGridView1_CellValueNeeded(object sender,
            System.Windows.Forms.DataGridViewCellValueEventArgs e)
        {


            listBox1.Items.Add($"dataGridView1_CellValueNeeded RowIndex {e.RowIndex}");
            // If this is the row for new records, no values are needed.
            if (e.RowIndex == this.dataGridView1.RowCount - 1) return;

            Customer customerTmp = null;

            // Store a reference to the Customer object for the row being painted.
            if (e.RowIndex == rowInEdit)
            {
                customerTmp = this.customerInEdit;
            }
            else
            {
                customerTmp = (Customer)this.customers[e.RowIndex];
            }

            // Set the cell value to paint using the Customer object retrieved.
            switch (this.dataGridView1.Columns[e.ColumnIndex].Name)
            {
                case "Company Name":
                    e.Value = customerTmp.CompanyName;
                    break;

                case "Contact Name":
                    e.Value = customerTmp.ContactName;
                    break;
            }
        }

        private void dataGridView1_CellValuePushed(object sender,
            System.Windows.Forms.DataGridViewCellValueEventArgs e)
        {
            Customer customerTmp = null;

            // Store a reference to the Customer object for the row being edited.
            if (e.RowIndex < this.customers.Count)
            {
                // If the user is editing a new row, create a new Customer object.
                this.customerInEdit ??= new Customer(
                    ((Customer)this.customers[e.RowIndex]).CompanyName,
                    ((Customer)this.customers[e.RowIndex]).ContactName);
                customerTmp = this.customerInEdit;
                this.rowInEdit = e.RowIndex;
            }
            else
            {
                customerTmp = this.customerInEdit;
            }

            // Set the appropriate Customer property to the cell value entered.
            String newValue = e.Value as String;
            switch (this.dataGridView1.Columns[e.ColumnIndex].Name)
            {
                case "Company Name":
                    customerTmp.CompanyName = newValue;
                    break;

                case "Contact Name":
                    customerTmp.ContactName = newValue;
                    break;
            }
        }

        private void dataGridView1_NewRowNeeded(object sender,
            System.Windows.Forms.DataGridViewRowEventArgs e)
        {
            // Create a new Customer object when the user edits
            // the row for new records.
            this.customerInEdit = new Customer();
            this.rowInEdit = this.dataGridView1.Rows.Count - 1;
        }

        private void dataGridView1_RowValidated(object sender,
            System.Windows.Forms.DataGridViewCellEventArgs e)
        {
            // Save row changes if any were made and release the edited
            // Customer object if there is one.
            if (e.RowIndex >= this.customers.Count &&
                e.RowIndex != this.dataGridView1.Rows.Count - 1)
            {
                // Add the new Customer object to the data store.
                this.customers.Add(this.customerInEdit);
                this.customerInEdit = null;
                this.rowInEdit = -1;
            }
            else if (this.customerInEdit != null &&
                     e.RowIndex < this.customers.Count)
            {
                // Save the modified Customer object in the data store.
                this.customers[e.RowIndex] = this.customerInEdit;
                this.customerInEdit = null;
                this.rowInEdit = -1;
            }
            else if (this.dataGridView1.ContainsFocus)
            {
                this.customerInEdit = null;
                this.rowInEdit = -1;
            }
        }

        private void dataGridView1_RowDirtyStateNeeded(object sender,
            System.Windows.Forms.QuestionEventArgs e)
        {
            if (!rowScopeCommit)
            {
                // In cell-level commit scope, indicate whether the value
                // of the current cell has been modified.
                e.Response = this.dataGridView1.IsCurrentCellDirty;
            }
        }

        private void dataGridView1_CancelRowEdit(object sender,
            System.Windows.Forms.QuestionEventArgs e)
        {
            if (this.rowInEdit == this.dataGridView1.Rows.Count - 2 &&
                this.rowInEdit == this.customers.Count)
            {
                // If the user has canceled the edit of a newly created row,
                // replace the corresponding Customer object with a new, empty one.
                this.customerInEdit = new Customer();
            }
            else
            {
                // If the user has canceled the edit of an existing row,
                // release the corresponding Customer object.
                this.customerInEdit = null;
                this.rowInEdit = -1;
            }
        }

        private void dataGridView1_UserDeletingRow(object sender,
            System.Windows.Forms.DataGridViewRowCancelEventArgs e)
        {
            if (e.Row.Index < this.customers.Count)
            {
                // If the user has deleted an existing row, remove the
                // corresponding Customer object from the data store.
                this.customers.RemoveAt(e.Row.Index);
            }

            if (e.Row.Index == this.rowInEdit)
            {
                // If the user has deleted a newly created row, release
                // the corresponding Customer object.
                this.rowInEdit = -1;
                this.customerInEdit = null;
            }
        }

        private void btnClearLb_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...