How to prevent a scrollbar from jumping when an inner control get focus.

I have a form with certain container, that haves a group of grids.  The container haves a scrollbar that
If the grid is partially hidden, when pressing the grid, it "select" the cell but at the same time it adjust host scrollbar in order to make all the grid in use visible. (Actually I have a code that unselect it inmediately, handlling the SelectionChanged event)
Inside the grids I have links that redirect to other parts of program.
Under normal conditions is a desirable behavior, but problem is that when clicking a link the "jump" prevents the link event to be called.
I tried to prevent selection and didn't found a way to do it (also not 100% sure it will help), also tried to prevent the "jump" on the scrollbar, with Scroll event, and wasn't fired on this reposition.
After playing a little bit it seems that is more related to focus than other things ( after doing it once it doesn't occur again until you select different grid)
So I need in any case to prevent the jump for permit the link work correctly, (maybe a way of prevent the adjustment of scrollbar when getting focus, or prevent the focus itself)
Any suggestion?

(On the code snippet below I didn't added the unselection code but is here just in case)
        private void dataGridView3_SelectionChanged(object sender, EventArgs e)
            dataGridView3.SelectionChanged -= new System.EventHandler(dataGridView1_SelectionChanged);

            dataGridView3.SelectionChanged += new System.EventHandler(dataGridView1_SelectionChanged);

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace test
    public partial class Form2 : Form
        public Form2()
        private void Form2_Load(object sender, EventArgs e)
            DataTable DT = new DataTable();
            DT.Columns.Add("ID", Type.GetType("System.Int32"));
            DT.Columns.Add("Name", Type.GetType("System.String"));
            DataRow DR = DT.NewRow();
            DR["ID"] = 1;
            DR["Name"] = "John";
            DR = DT.NewRow();
            DR["ID"] = 2;
            DR["Name"] = "Joe";
            DR = DT.NewRow();
            DR["ID"] = 3;
            DR["Name"] = "Mary";
            DR = DT.NewRow();
            DR["ID"] = 4;
            DR["Name"] = "Sarah";
            DR = DT.NewRow();
            DR["ID"] = 5;
            DR["Name"] = "Jack";
            dataGridView1.DataSource = DT;
            dataGridView2.DataSource = DT;
            dataGridView3.DataSource = DT;
            DataGridViewLinkColumn LinkC = new DataGridViewLinkColumn();
            DataGridViewColumn DC = dataGridView3.Columns["Name"];
            LinkC.Name = "Name";
            LinkC.LinkBehavior = LinkBehavior.HoverUnderline;
            LinkC.HeaderText = DC.HeaderText;
            LinkC.DataPropertyName = DC.DataPropertyName;
            LinkC.LinkColor = Color.Blue;
            LinkC.TrackVisitedState = false;
            LinkC.DisplayIndex = DC.DisplayIndex;
        private void dataGridView3_CellContentClick(object sender, DataGridViewCellEventArgs e)
            if (IsANonHeaderLinkCell(e))
                MessageBox.Show((dataGridView1.Rows[e.RowIndex].DataBoundItem as DataRowView).Row["Name"] as string);
        private bool IsANonHeaderLinkCell(DataGridViewCellEventArgs cellEvent)
            if (dataGridView3.Columns[cellEvent.ColumnIndex] is
                DataGridViewLinkColumn &&
                cellEvent.RowIndex != -1)
            { return true; }
            else { return false; }
namespace test
    partial class Form2
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
            if (disposing && (components != null))
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.dataGridView2 = new System.Windows.Forms.DataGridView();
            this.dataGridView3 = new System.Windows.Forms.DataGridView();
            // tableLayoutPanel1
            this.tableLayoutPanel1.ColumnCount = 1;
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
            this.tableLayoutPanel1.Controls.Add(this.dataGridView3, 0, 2);
            this.tableLayoutPanel1.Controls.Add(this.dataGridView2, 0, 1);
            this.tableLayoutPanel1.Controls.Add(this.dataGridView1, 0, 0);
            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
            this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
            this.tableLayoutPanel1.RowCount = 3;
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 42.48555F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 57.51445F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 200F));
            this.tableLayoutPanel1.Size = new System.Drawing.Size(404, 700);
            this.tableLayoutPanel1.TabIndex = 0;
            // dataGridView1
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView1.Location = new System.Drawing.Point(3, 3);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.Size = new System.Drawing.Size(398, 206);
            this.dataGridView1.TabIndex = 0;
            // dataGridView2
            this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView2.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView2.Location = new System.Drawing.Point(3, 215);
            this.dataGridView2.Name = "dataGridView2";
            this.dataGridView2.Size = new System.Drawing.Size(398, 281);
            this.dataGridView2.TabIndex = 1;
            // dataGridView3
            this.dataGridView3.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView3.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView3.Location = new System.Drawing.Point(3, 502);
            this.dataGridView3.Name = "dataGridView3";
            this.dataGridView3.Size = new System.Drawing.Size(398, 195);
            this.dataGridView3.TabIndex = 2;
            this.dataGridView3.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView3_CellContentClick);
            // Form2
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.AutoScroll = true;
            this.ClientSize = new System.Drawing.Size(421, 547);
            this.Name = "Form2";
            this.Text = "Form2";
            this.Load += new System.EventHandler(this.Form2_Load);
        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
        private System.Windows.Forms.DataGridView dataGridView3;
        private System.Windows.Forms.DataGridView dataGridView2;
        private System.Windows.Forms.DataGridView dataGridView1;

Open in new window

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.


I'm not sure I completely understand your problem.  Do you mean that a link will jump to another grid, and the scroll bar doesn't cooperate?  I would set focus to the grid, then select the row...

But I need more information to help you further.

AbrahamBensicsuAuthor Commented:
Hi Jake072

the problem is that when i press link and grid is partially hidden, instead of firing link event, the scrollbar adjusts in order to make all the grid visible, and prevents the link event to occur (seems that adjustment occurs on mousedown and link after this)

I see what you mean now.  If you set a breakpoint in the LinkClick event, does it get fired?

As for the scrollbar moving, that is built into the control, to make sure that it's visible, not much can be done there, but we might be able to conjure a hack for the LinkClick event.

Let me know, and we'll go from there,

Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

AbrahamBensicsuAuthor Commented:
Hi Jake072

In the code above I made a message Box to pop-up in the link event, and it doesn't get fired at all (also tried with breakpoint no luck)
I just tried with a CellMouseDown event handler it seems to enter to the event before auto-fit the grid, but still not clear if I can check if link was actually pressed..
So any hack for link is welcome :)

Have you tried testing in CellMouseDown to see if the link has focus?  I'm not at my dev machine to try, sorry.

Will look into it for you though.

AbrahamBensicsuAuthor Commented:
Hi Jake072
What I had done on mouse Down is:
 private void dataGridView3_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
and it writes the line on the debug window before the scrollbar moves to fit the grid to be visible,
But I can't check inside this event if the link has been clicked or it is a click outside the link, we have within the event parameters the location of the mouse but this is not enough to determine if link was clicked.
Ideal option would be to prevent the focus/skipping of scrollbar, or even returning scrollbar to position at click time (this also I tried but was to no avail... maybe you have a solution for me on this side)

AbrahamBensicsuAuthor Commented:
Hi again,

Sorry... actually I see mousedown is fired after adjusting the scrollbar.
But  e.ColumnIndex and  e.RowIndex are correct as values of clicked cell.

Maybe if we could have a way to determine if shape of mouse is "hand" instead of "pointer" we can determine if link was clicked or empty area of cell was clicked.  

Any suggestion is welcome!
 thanks again
AbrahamBensicsuAuthor Commented:
Hi Jake072..

    A little  bit long wait... but I had found workaround, that at least work for me now; as you noted is not possible to prevent the scrollbar completely from jump, but I found something that delay the jump.  
   After playing with events a ltitle bit I found that the value of scrollbar is changed between  Enter and GotFocus event, so keeping it in a temp variable, and setting up again does the work.  When I finally leave mouse it will jump again, but this is after link event is fired :)
     Thx in any case

 int vval;
  void dataGridView3_Enter(object sender, EventArgs e)
            vval = this.VerticalScroll.Value;
        void dataGridView3_GotFocus(object sender, EventArgs e)
            this.VerticalScroll.Value = vval;

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial

I'm glad you found a solution.  I was experimenting with the same thing...

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.