Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Speeding up DataGridView RowCount assignment

Speeding up DataGridView RowCount assignment

Scheduled Pinned Locked Moved C#
performancehelptutorialquestionlounge
11 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A AndrusM

    In code below Line m_Grid.RowCount = 1000000; takes 8 seconds. How to speed it up ? Andrus.

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

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

    class VirtualModeForm : Form
    {
    private List<DataObject> m_Data = new List<DataObject>();
    private List<bool> m_Visited = new List<bool>();
    DataGridView m_Grid = new DataGridView();
    public VirtualModeForm()
    {
    Controls.Add(m_Grid);
    m_Grid.CellValueNeeded += OnCellValueNeeded;
    InitData();
    InitGrid();
    }

    private void InitData()
    {
        for (int i = 0; i < 1000001 + 1; i++)
        {
            m\_Visited.Add(false);
            DataObject obj = new DataObject();
            obj.Id = i;
            obj.Val = 2 \* i;
            m\_Data.Add(obj);
        }
    }
    
    private void InitGrid()
    {
        m\_Grid.Dock = DockStyle.Fill;
        m\_Grid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCellsExceptHeader);
        m\_Grid.VirtualMode = true;
        m\_Grid.ReadOnly = true;
        m\_Grid.ColumnCount = 108;
        // this line causes 8 seconds delay. how to fix.
        m\_Grid.RowCount = 1000000;
    }
    
    private void OnCellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
    
        m\_Visited\[e.RowIndex\] = true;
        if (e.ColumnIndex == 0)
        {
            e.Value = m\_Data\[e.RowIndex\].Id;
        }
        else if (e.ColumnIndex == 1)
        {
            e.Value = m\_Data\[e.RowIndex\].Val;
        }
        else if (e.ColumnIndex == 2)
        {
    
            Random rand = new Random();
            e.Value = rand.Next();
        }
    }
    

    }

    public class DataObject
    {
    private int m_Id;
    private int m_Val;

    public int Val
    {
        get { return m\_Val; }
        set { m\_Val = value; }
    }
    
    public int Id
    {
        get { return m\_Id; }
        set { m\_Id = value; }
    }
    
    public int Id1 { get; set; }
    public int Id2 { get; set; }
    public int Id3 { get; set; }
    public int Id4 { get; set; }
    public int Id5 { get; set; }
    public int Id6 { get; set; }
    public int Id7 { get; set; }
    public int Id8 { get; set; }
    public int Id9 { get; set; }
    public int Id10 { get; set; }
    public int Id11 { get; set; }
    public int Id12 { get; set;
    
    W Offline
    W Offline
    Wendelius
    wrote on last edited by
    #2

    If you're already using virtual mode, why set the row count so high. Try a smaller value like 100. When additional rows are needed, CellValueNeeded should provide them from a store like datatable, array etc.

    The need to optimize rises from a bad design. My articles[^]

    A 1 Reply Last reply
    0
    • W Wendelius

      If you're already using virtual mode, why set the row count so high. Try a smaller value like 100. When additional rows are needed, CellValueNeeded should provide them from a store like datatable, array etc.

      The need to optimize rises from a bad design. My articles[^]

      A Offline
      A Offline
      AndrusM
      wrote on last edited by
      #3

      Fake Rowcount causes the following issues: 1. It is not possible to see more rows: you can navigate only between first 100 rows. No way to go to row number 101. 2. Buttor in vertical scrollbar does not show real position in table. For real rowcount, button indicates visually real position: in the start, in middle or in end of table. So it is impossible to use fake rowcount.

      Andrus

      W 1 Reply Last reply
      0
      • A AndrusM

        In code below Line m_Grid.RowCount = 1000000; takes 8 seconds. How to speed it up ? Andrus.

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

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

        class VirtualModeForm : Form
        {
        private List<DataObject> m_Data = new List<DataObject>();
        private List<bool> m_Visited = new List<bool>();
        DataGridView m_Grid = new DataGridView();
        public VirtualModeForm()
        {
        Controls.Add(m_Grid);
        m_Grid.CellValueNeeded += OnCellValueNeeded;
        InitData();
        InitGrid();
        }

        private void InitData()
        {
            for (int i = 0; i < 1000001 + 1; i++)
            {
                m\_Visited.Add(false);
                DataObject obj = new DataObject();
                obj.Id = i;
                obj.Val = 2 \* i;
                m\_Data.Add(obj);
            }
        }
        
        private void InitGrid()
        {
            m\_Grid.Dock = DockStyle.Fill;
            m\_Grid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCellsExceptHeader);
            m\_Grid.VirtualMode = true;
            m\_Grid.ReadOnly = true;
            m\_Grid.ColumnCount = 108;
            // this line causes 8 seconds delay. how to fix.
            m\_Grid.RowCount = 1000000;
        }
        
        private void OnCellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
        
            m\_Visited\[e.RowIndex\] = true;
            if (e.ColumnIndex == 0)
            {
                e.Value = m\_Data\[e.RowIndex\].Id;
            }
            else if (e.ColumnIndex == 1)
            {
                e.Value = m\_Data\[e.RowIndex\].Val;
            }
            else if (e.ColumnIndex == 2)
            {
        
                Random rand = new Random();
                e.Value = rand.Next();
            }
        }
        

        }

        public class DataObject
        {
        private int m_Id;
        private int m_Val;

        public int Val
        {
            get { return m\_Val; }
            set { m\_Val = value; }
        }
        
        public int Id
        {
            get { return m\_Id; }
            set { m\_Id = value; }
        }
        
        public int Id1 { get; set; }
        public int Id2 { get; set; }
        public int Id3 { get; set; }
        public int Id4 { get; set; }
        public int Id5 { get; set; }
        public int Id6 { get; set; }
        public int Id7 { get; set; }
        public int Id8 { get; set; }
        public int Id9 { get; set; }
        public int Id10 { get; set; }
        public int Id11 { get; set; }
        public int Id12 { get; set;
        
        L Offline
        L Offline
        Luc Pattyn
        wrote on last edited by
        #4

        Hi, do some research on DataGridView.VirtualMode, that is the official way to handle insane amounts of data in a reasonable time. I haven't used it myself yet, so I won't be able to explain from experience. :)

        Luc Pattyn [Forum Guidelines] [My Articles]


        Fixturized forever. :confused:


        A 1 Reply Last reply
        0
        • A AndrusM

          Fake Rowcount causes the following issues: 1. It is not possible to see more rows: you can navigate only between first 100 rows. No way to go to row number 101. 2. Buttor in vertical scrollbar does not show real position in table. For real rowcount, button indicates visually real position: in the start, in middle or in end of table. So it is impossible to use fake rowcount.

          Andrus

          W Offline
          W Offline
          Wendelius
          wrote on last edited by
          #5

          Sorry, wrote that in a hurry. Rowcount is the actual amount which is used to define scroll size. If you have wired CellValueNeeded correctly, it should work fine. Have you checked that CellValueNeeded is actually used and is it called (several times) when you set the rowcount. Another thing is that you have automatic sizes for columns. That may slow this quite a lot. Try commenting it out and test if any change.

          The need to optimize rises from a bad design. My articles[^]

          A 1 Reply Last reply
          0
          • L Luc Pattyn

            Hi, do some research on DataGridView.VirtualMode, that is the official way to handle insane amounts of data in a reasonable time. I haven't used it myself yet, so I won't be able to explain from experience. :)

            Luc Pattyn [Forum Guidelines] [My Articles]


            Fixturized forever. :confused:


            A Offline
            A Offline
            AndrusM
            wrote on last edited by
            #6

            Lyc, as you see from my sample it already uses VirtualMode. The issue is that increasing number of rows decreases RowCount setting speed. This should not happen.

            Andrus

            L 1 Reply Last reply
            0
            • A AndrusM

              Lyc, as you see from my sample it already uses VirtualMode. The issue is that increasing number of rows decreases RowCount setting speed. This should not happen.

              Andrus

              L Offline
              L Offline
              Luc Pattyn
              wrote on last edited by
              #7

              Hi, I suggest you study some examples, and observe your code as to what exactly is going on. As in: how many ValueNeeded events do fire, and how many items are visible at one time. If there is a mismatch, then that is the problem. The basic concept is the DGV should only fire ValueNeeded for items that have to be drawn. BTW are you sure you want over 100 columns? and all those get/set properties? it does not look right. Also I don't like the two lists of properties, the only data you should need is a list of items. Avoid redundancy! :)

              Luc Pattyn [Forum Guidelines] [My Articles]


              Fixturized forever. :confused:


              A 1 Reply Last reply
              0
              • W Wendelius

                Sorry, wrote that in a hurry. Rowcount is the actual amount which is used to define scroll size. If you have wired CellValueNeeded correctly, it should work fine. Have you checked that CellValueNeeded is actually used and is it called (several times) when you set the rowcount. Another thing is that you have automatic sizes for columns. That may slow this quite a lot. Try commenting it out and test if any change.

                The need to optimize rises from a bad design. My articles[^]

                A Offline
                A Offline
                AndrusM
                wrote on last edited by
                #8

                Mika, thank you for reply. Tried tried the following: 1. OnCellValueNeeded is not called: F11 steps to next line after 8 sec delay. Debug output window shows a lot of messagers "skipping over non-user code". Delay seems to occur after those messages are output. 2. I removed m_Grid.AutoResizeColumns line and tried with DataGridViewAutoSizeColumnsMode.None Delay still occurs. I'm wondering why number or rows affects to this delay. VirtualMode must be designed to avoid this. Is it possible to use other control to create editable virtual grid ? I looked SourceGrid in http://www.devage.com/[^] but it last update was a year ago so it seems not maintained. Those grids are used frequently in my application in UI. Data for visibla part of a grid grid is retrieved from database for 4 seconds due to virtualization. It is not reasonable to force user to wait 8 seconds for a grid to render. Any idea how to fix this ?

                Andrus

                1 Reply Last reply
                0
                • L Luc Pattyn

                  Hi, I suggest you study some examples, and observe your code as to what exactly is going on. As in: how many ValueNeeded events do fire, and how many items are visible at one time. If there is a mismatch, then that is the problem. The basic concept is the DGV should only fire ValueNeeded for items that have to be drawn. BTW are you sure you want over 100 columns? and all those get/set properties? it does not look right. Also I don't like the two lists of properties, the only data you should need is a list of items. Avoid redundancy! :)

                  Luc Pattyn [Forum Guidelines] [My Articles]


                  Fixturized forever. :confused:


                  A Offline
                  A Offline
                  AndrusM
                  wrote on last edited by
                  #9

                  Luc, Thank you. MSDN has DataGridView_Samples.zip which contains two VirtualMode grid samples and a doc file covering VirtualMode a bit. Part of samples from this file are also duplicated in MSDN doc code samples. MSDN forums contains also some few messages about VirtualMode. There is also a Chris Cells book. The sample code presented here is modified sample from this book. My code is based on this information. I have looked first 100 pages returned from google search. I havent found any other information about DataGridView VirtualMode. Pressing F11 in RowCount moves to next line after delay. So OnCellValueNeeded method not any other lines in my code are not called. In real application I have wide Product tables which can contain 100 columns. They appear fine in wide LCD screen. Reducing number of columns to 50 causes also long delay. I'm sorry for a bad sample. Below is minimal code to reproduce 8 sec delay issue.

                  using System;
                  using System.Windows.Forms;

                  class Test
                  {
                  public static void Main()
                  {
                  Application.Run(new VirtualModeForm());
                  }
                  }

                  class VirtualModeForm : Form
                  {
                  DataGridView grid = new DataGridView();
                  public VirtualModeForm()
                  {
                  Controls.Add(grid);
                  grid.VirtualMode = true;
                  grid.ColumnCount = 108;
                  // this line causes 8 seconds delay.
                  grid.RowCount = 1000000;
                  }
                  }

                  Andrus

                  L 1 Reply Last reply
                  0
                  • A AndrusM

                    Luc, Thank you. MSDN has DataGridView_Samples.zip which contains two VirtualMode grid samples and a doc file covering VirtualMode a bit. Part of samples from this file are also duplicated in MSDN doc code samples. MSDN forums contains also some few messages about VirtualMode. There is also a Chris Cells book. The sample code presented here is modified sample from this book. My code is based on this information. I have looked first 100 pages returned from google search. I havent found any other information about DataGridView VirtualMode. Pressing F11 in RowCount moves to next line after delay. So OnCellValueNeeded method not any other lines in my code are not called. In real application I have wide Product tables which can contain 100 columns. They appear fine in wide LCD screen. Reducing number of columns to 50 causes also long delay. I'm sorry for a bad sample. Below is minimal code to reproduce 8 sec delay issue.

                    using System;
                    using System.Windows.Forms;

                    class Test
                    {
                    public static void Main()
                    {
                    Application.Run(new VirtualModeForm());
                    }
                    }

                    class VirtualModeForm : Form
                    {
                    DataGridView grid = new DataGridView();
                    public VirtualModeForm()
                    {
                    Controls.Add(grid);
                    grid.VirtualMode = true;
                    grid.ColumnCount = 108;
                    // this line causes 8 seconds delay.
                    grid.RowCount = 1000000;
                    }
                    }

                    Andrus

                    L Offline
                    L Offline
                    Luc Pattyn
                    wrote on last edited by
                    #10

                    Hi Andrus, I did a little experiment with your code. Observations: - time elapsed is proportional to number of rows; - time elapsed heavily depends (not proportional) on number of columns - setting RowCount first is a lot faster. Conclusions: 1) the DGV seems to create objects for all the cells right from the start, and creating 108 million objects is bound to take a couple of seconds. 2) for unknown reasons RowCount-first is faster BTW: you should not add the grid to Controls before it has been set up. :)

                    Luc Pattyn [Forum Guidelines] [My Articles]


                    Fixturized forever. :confused:


                    A 1 Reply Last reply
                    0
                    • L Luc Pattyn

                      Hi Andrus, I did a little experiment with your code. Observations: - time elapsed is proportional to number of rows; - time elapsed heavily depends (not proportional) on number of columns - setting RowCount first is a lot faster. Conclusions: 1) the DGV seems to create objects for all the cells right from the start, and creating 108 million objects is bound to take a couple of seconds. 2) for unknown reasons RowCount-first is faster BTW: you should not add the grid to Controls before it has been set up. :)

                      Luc Pattyn [Forum Guidelines] [My Articles]


                      Fixturized forever. :confused:


                      A Offline
                      A Offline
                      AndrusM
                      wrote on last edited by
                      #11

                      Luc, 2) for unknown reasons RowCount-first is faster Thank you very much. You are genious. I tried this in my applicaton and this eliminates RowCount delay. Now there is only 3 sec delay which is caused by reading first two pages to cache like in MSDN sample. There is also SELECT COUNT(*) FROM mytable command but this seems not to cause any delay. the DGV seems to create objects for all the cells right from the start, and creating 108 million objects is bound to take a couple 108 millions of objects should take visible in Task Manager amout of memory. Task Manager memory (working set) does not show significat memory consumption. So I think that 108 million of objects are not created. Maybe this is related to sililar issue which posted here and in MS product feedback and which does not have any solution: Steps to reproduce: 1. Run code below 2. Double click in grid header in separation line between columns 1 ja 2 Observed: CPU usage goes to 100% for a long time. using System; using System.Windows.Forms; using System.Collections.Generic; class test { [STAThreadAttribute()] public static void Main() { Application.Run(new VirtualModeForm()); } } class VirtualModeForm : Form { private List<DataObject> m_Data = new List<DataObject>(); private List<bool> m_Visited = new List<bool>(); DataGridView m_Grid = new DataGridView(); public VirtualModeForm() { Controls.Add(m_Grid); m_Grid.CellValueNeeded += OnCellValueNeeded; InitData(); InitGrid(); } private void InitData() { for (int i = 0; i < 1000001 + 1; i++) { m_Visited.Add(false); DataObject obj = new DataObject(); obj.Id = i; obj.Val = 2 * i; m_Data.Add(obj); } } private void InitGrid() { m_Grid.Dock = DockStyle.Fill; m_Grid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCellsExceptHeader); m_Grid.VirtualMode = true; m_Grid.ReadOnly = true; m_Grid.ColumnCount = 3; m_Grid.Rows.Add(); m_Grid.Rows.AddCopies(0, 1000000); } private void OnCellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { m_Visited[e.RowIndex] = true; if (e.ColumnIndex == 0) { e.Value = m_Data[e.RowIndex].Id; } else if (e.ColumnIndex == 1) { e.Value = m_Data[e.RowIndex].Val; } else if (e.ColumnIndex == 2) { Random rand = new Random(); e.Value = rand.Next(); } } } public class DataObject { private int m_Id; private int m_Val; public int Val { get { return m_Val; } set { m_Val = value; } } public int Id { get { return m_

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups