• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1942
  • Last Modified:

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.ClearSelection();
            dataGridView3.SelectionChanged += new System.EventHandler(dataGridView1_SelectionChanged);

        }
///code
 
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()
        {
            InitializeComponent();
        }
 
        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";
            DT.Rows.Add(DR);
            DR = DT.NewRow();
            DR["ID"] = 2;
            DR["Name"] = "Joe";
            DT.Rows.Add(DR);
            DR = DT.NewRow();
            DR["ID"] = 3;
            DR["Name"] = "Mary";
            DT.Rows.Add(DR);
            DR = DT.NewRow();
            DR["ID"] = 4;
            DR["Name"] = "Sarah";
            DT.Rows.Add(DR);
            DR = DT.NewRow();
            DR["ID"] = 5;
            DR["Name"] = "Jack";
            DT.Rows.Add(DR);
 
            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;
            dataGridView3.Columns.Remove(DC);
            dataGridView3.Columns.Add(LinkC);
 
        }
 
        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; }
        }
 
 
    }
}
 
//designer
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))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #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();
            this.tableLayoutPanel1.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView3)).BeginInit();
            this.SuspendLayout();
            // 
            // 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.Controls.Add(this.tableLayoutPanel1);
            this.Name = "Form2";
            this.Text = "Form2";
            this.Load += new System.EventHandler(this.Form2_Load);
            this.tableLayoutPanel1.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView3)).EndInit();
            this.ResumeLayout(false);
 
        }
 
        #endregion
 
        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

0
AbrahamBensicsu
Asked:
AbrahamBensicsu
  • 5
  • 4
2 Solutions
 
jake072Commented:
AbrahamBensicsu,

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.

Jake
0
 
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)
picture1.bmp
picture2.bmp
0
 
jake072Commented:
AbrahamBensicsu,

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,

Jake
0
Industry Leaders: 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!

 
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 :)
0
 
jake072Commented:
AbrahamBensicsu,

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.

Jake
0
 
AbrahamBensicsuAuthor Commented:
Hi Jake072
What I had done on mouse Down is:
 private void dataGridView3_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("down");
        }
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)

Thanks
0
 
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
0
 
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

0
 
jake072Commented:
AbrahamBensicsu,

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

Jake
0

Featured Post

Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now