Solved

Update Winforms Datagridviews vertical scrollbar thumb(tab) position and size

Posted on 2010-08-12
12
2,655 Views
Last Modified: 2013-12-17
How to repaint the entire datagridview region (I need to update the datagridviews vertical scrollbar thumb(tab) position and size as datagridview data source is added.)
I am updating datatable (which is datagridview datasource on a separate thread) and after adding the new row to datatable, i am calling the invalidate method of the datagridview. Even after invalidating the entire region of datagridview, the vertical scrollbar thumb(tab) position and size as datagridview are not updated.
Could anyone please suggest/comment on this?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace GridViewScrollBar
{
    public partial class Form1 : Form
    {
        static int counter;
        //Datatable to which datarows are added on seperate thread
        DataTable dataTable;

        // Declaring delegate
        public delegate void DeleRefreshDataGridView();

        //Declaring event
        DeleRefreshDataGridView deleRefreshDataGridView;         

        public Form1()
        {
            InitializeComponent();

            dataTable = new DataTable();
            dataTable.Columns.Add(new DataColumn("Name"));
            dataTable.Columns.Add(new DataColumn("City"));

            //Delegate to refresh the datagridview upon row addion.
            deleRefreshDataGridView = new DeleRefreshDataGridView(RefreshDataGridView);

            dataTable.TableNewRow += new DataTableNewRowEventHandler(dataTable_TableNewRow);

            dataGridView1.DataSource = dataTable;

        }


        void dataTable_TableNewRow(object sender, DataTableNewRowEventArgs e)
        {
            dataGridView1.Invoke(deleRefreshDataGridView);            
        }
       
        public void AddData()
        {            
            for (int i = 0; i < 100000; i++)
            {
                DataRow dataRow = dataTable.NewRow();
                dataRow["Name"] = "Name " + i;
                dataRow["City"] = "City " + i;

                dataTable.Rows.Add(dataRow);                 
            }
        }
        private void RefreshDataGridView()
        {
          dataGridView1.Refresh();
          dataGridView1.PerformLayout();
          counter++;

	  //Uncomment the below line to see the datagridview scrollbar updating but the rows position is changed. That should not happen.
          // dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count-1;
         
          
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(AddData));
            thread.Start();
        }
    }
}

Open in new window

0
Comment
Question by:mkarthik415
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 3
  • +1
12 Comments
 
LVL 16

Expert Comment

by:kris_per
ID: 33425719


VScrollBar is a child control of dataGridView and you can get it from dataGridView1.Controls collection and setting the Maximum and Value properties of VScrollBar control will move the scroll bars...see if you can do something with this...
0
 

Author Comment

by:mkarthik415
ID: 33426031
Hi Kris per

Thank you for the quick response. I tried to loop thru all the child controls of datagridview and repaint them like this.

            for (int i = 0; i < dataGridView1.Controls.Count; i++)
            {
                if (dataGridView1.Controls.GetType().ToString() == "VScrollBar")
                {
                    verticalScrollBar = (VScrollBar)dataGridView1.Controls[i];
                    verticalScrollBar.PerformLayout();
                    break;
                }
            }


But even this didnt work?

Thank You
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
ID: 33427005
Hi,

Check code.

Regards,
V.S.Saini

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

namespace GridViewScrollBar
{
    public partial class Form1 : Form
    {
        static int counter;
        //Datatable to which datarows are added on seperate thread
        DataTable dataTable;

        // Declaring delegate
        public delegate void DeleRefreshDataGridView();

        //Declaring event
        DeleRefreshDataGridView deleRefreshDataGridView;         

        public Form1()
        {
            InitializeComponent();

            dataTable = new DataTable();
            dataTable.Columns.Add(new DataColumn("Name"));
            dataTable.Columns.Add(new DataColumn("City"));

            //Delegate to refresh the datagridview upon row addion.
            deleRefreshDataGridView = new DeleRefreshDataGridView(RefreshDataGridView);

            dataTable.TableNewRow += new DataTableNewRowEventHandler(dataTable_TableNewRow);

            dataGridView1.DataSource = dataTable;

        }


        void dataTable_TableNewRow(object sender, DataTableNewRowEventArgs e)
        {
            dataGridView1.Invoke(deleRefreshDataGridView);            
        }
       
        public void AddData()
        {            
            for (int i = 0; i < 100000; i++)
            {
                DataRow dataRow = dataTable.NewRow();
                dataRow["Name"] = "Name " + i;
                dataRow["City"] = "City " + i;

                dataTable.Rows.Add(dataRow);                 
            }
        }
        private void RefreshDataGridView()
        {
          dataGridView1.Refresh();
          dataGridView1.PerformLayout();
          
           // Set dataGridView FirstRow index          
            //dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count - 1;          

            foreach (Control control in this.dataGridView1.Controls)
            {
                if (control is VScrollBar)
                {
                    VScrollBar vscroll = (VScrollBar)control;
                    if (vscroll.Visible)
                        vscroll.Value = vscroll.Maximum;
                }
            }
          
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(AddData));
            thread.Start();
        }
    }
}

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 14

Expert Comment

by:systan
ID: 33428913
You can update the position with that code.
dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.GetLastRow(0)].Cells[0];

Open in new window

0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
ID: 33428996
Hello @systan,

I tried your code earlier in RefreshDataGridView(). And it returns back as

Operation  is not valid because it results in a reentrant call to the  SetCurrentCellAddressCore function.

Thanks  and Regards,
VSS
0
 
LVL 14

Expert Comment

by:systan
ID: 33430651
Why do you have to  RefreshDataGridView when if position to the one you like.
 RefreshDataGridView refreshes the grid, so that's why it returns to the top position.
0
 

Author Comment

by:mkarthik415
ID: 33431395
Hi systan

I am looking to update the Scrollbar thumb(tab) size along with its position. When new records are added, its size should be reduced and position should updated.

Thank You
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
ID: 33434767
Hello mkarthik415,

Do the answer I provided is not matching with your problem requirements.

Regards,
VSS
0
 

Author Comment

by:mkarthik415
ID: 33435007
Hi vs00saini

I really appreciate your work and interest toward my question. Sorry for delay in assigning the points.
Coming to the requirement, scrollbar's tab size and position should be updated. But in the above code, only the size is updated and the position is not updated. Scrollbar thumb is either at the top or bottom.
Once again, thank you very much vs00saini.

Regards
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
ID: 33435040
0
 
LVL 16

Expert Comment

by:kris_per
ID: 33436094

To move the scroll thumbs position VScrollBar control can be used by setting its Value property.

To actually scroll the rows in the grid, I just tried simulating click message on scroll bar's thumb and it seems to be working...

Code is below and hope this helps...

private void RefreshDataGridView()
        {
            dataGridView1.Refresh();
            dataGridView1.PerformLayout();
            counter++;

            if (counter == 2)
            {
                // just to show that the position/current cell remains 
                // the same when the scrolling happens
                dataGridView1.CurrentCell = dataGridView1[0, 0];
            }

            foreach (Control control in this.dataGridView1.Controls)
            {
                if (control is VScrollBar)
                {
                    VScrollBar vscroll = (VScrollBar)control;
                    if (vscroll.Visible)
                    {
                        // set scroll bar's thumb at the bottom which means we can see the last row...
                        vscroll.Value = vscroll.Maximum;
                             
                        // now send mouse down/up messages on scroll bar's thumb                   
                        Point p = new Point(10, vscroll.ClientSize.Height - 19);
                        int pos = MakeLParam(p.X, p.Y);
                        p = vscroll.PointToScreen(p);

                        SendMessage(vscroll.Handle, (int)WindowsMessages.WM_LBUTTONDOWN, 0, pos);
                        SendMessage(vscroll.Handle, (int)WindowsMessages.WM_LBUTTONUP, 0, pos);                                              
                    }
                }
            }

            //Uncomment the below line to see the datagridview scrollbar updating but the rows position is changed. That should not happen.
            // dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count-1;  
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        public int MakeLParam(int LoWord, int HiWord)
        {
            return ((HiWord << 16) | (LoWord & 0xffff));
        }

Open in new window

0
 
LVL 16

Accepted Solution

by:
kris_per earned 500 total points
ID: 33436106
Plus the below code as well:
public enum WindowsMessages : int
        {
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202,
        }

Open in new window

0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question