Home » VB.Net

using PreviewKeyDown event in DataGridView in winform to navigate using up and down arrows

We have a winform application using Oracle DataAccessClient. There is a gridview and textboxes where we when we click on a row we can populate the textboxes to show more of the data so the user does not have to scroll horizontally.  The code that does this is in the cell click event. We want to also do this if the user presses the up or down arrow. We put the code in the PreviewKeyDown event but we are getting the row that had the focus rather than the row that has the current arrow pointing to it. We searched the web at a lot of forums but we can not seem to locate how to do it. How do we move the focus to the row the arrow is pointing to in the grid? Here is the code:



Sub masterDataGridView_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles masterDataGridView.PreviewKeyDown


Dim objConnection2 AsNew OracleConnection(conStr)

objConnection2.ConnectionString = conStr


Dim mySQL AsString = ""





Dim objCommand AsNew OracleCommand()

objCommand.Connection = objConnection2


If masterDataGridView.CurrentRow.Cells(0).Value.ToString() <> ""Then


Dim objRrParm AsNew OracleParameter("rrparm", OracleDbType.Varchar2)

objRrParm.Value = masterDataGridView.CurrentRow.Cells(0).Value.ToString()


mySQL =

"select * from rr_record_requests where rr_number = :rrparm"





objCommand.CommandText = mySQL

objCommand.CommandType = System.Data.CommandType.Text


Dim RR_RECORD_REQUESTSTableAdapter AsNew OracleDataAdapter(objCommand)


Dim objTable AsNew DataTable()



'Me.masterDataGridView.DataSource = objTable

lblTotalRows.Text =

"Total rows returned = " + objTable.Rows.Count.ToString


If objTable.Rows.Count = 0 Then


"Record request not found")




Me.tbxRequestNumber.Text = Convert.ToString(objTable.Rows(0)("rr_number"))


Me.tbxFlName.Text = Convert.ToString(objTable.Rows(0)("requestor_fl_name"))


Me.tbxCompany.Text = Convert.ToString(objTable.Rows(0)("company"))


Me.tbxAddress.Text = Convert.ToString(objTable.Rows(0)("address"))


Me.tbxCity.Text = Convert.ToString(objTable.Rows(0)("city"))


Me.tbxState.Text = Convert.ToString(objTable.Rows(0)("state"))


Me.tbxZip.Text = Convert.ToString(objTable.Rows(0)("postal_code"))


Me.tbxTelephone.Text = Convert.ToString(objTable.Rows(0)("telephone"))


Me.tbxFax.Text = Convert.ToString(objTable.Rows(0)("fax"))


Me.tbxEmail.Text = Convert.ToString(objTable.Rows(0)("email_address"))


Me.tbxAgreeToPay.Text = Convert.ToString(objTable.Rows(0)("agreetopay_yn"))


Me.tbxRecElec.Text = Convert.ToString(objTable.Rows(0)("electronic_yn"))


Me.tbxElecDesc.Text = Convert.ToString(objTable.Rows(0)("electronic_desc"))


Me.tbxFirstName.Text = Convert.ToString(objTable.Rows(0)("first_name"))


Me.tbxLastName.Text = Convert.ToString(objTable.Rows(0)("last_name"))


Me.tbxPrevNames.Text = Convert.ToString(objTable.Rows(0)("previous_names"))


Me.tbxSsn.Text = Convert.ToString(objTable.Rows(0)("ssn"))


Me.tbxDoi.Text = Convert.ToString(objTable.Rows(0)("date_of_injury"))


Me.tbxDob.Text = Convert.ToString(objTable.Rows(0)("date_of_birth"))


Me.tbxDesc.Text = Convert.ToString(objTable.Rows(0)("description"))


Me.tbxOriginSrc.Text = Convert.ToString(objTable.Rows(0)("origin_source"))


Me.tbxOriginDate.Text = Convert.ToString(objTable.Rows(0)("origin_date"))


Me.tbxChangeSrc.Text = Convert.ToString(objTable.Rows(0)("change_source"))


Me.tbxChangeDate.Text = Convert.ToString(objTable.Rows(0)("change_date"))





Catch ex As Exception












2 Answers Found


Answer 1

Hi Bmayfield,


Welcome to MSDN forums!


I modify your code layout to make your post more readable.

By the way, you can consider posting it at Windows Forms Data Controls and Databinding Forum for better support.


Best regards,

Martin Xie


Answer 2

Thanks. Posted question in Windows Forms Data Controls and Databinding Forum




I have a structure on my Form like this. Form contains TableLayout, each cell in TableLayout contains Panel, each Panel has a PictureBox and a Label inside it. When the user selects the "Directional Navigation" mode, he/she is given an option to navigate between PictureBoxes on the Form using the Direction Keys. I did automatic shifiting of focus between different picture boxes but haven't been able to do this using direction keys. Please help!



I have a structure on my Form like this.

Form contains TableLayout , each cell in TableLayout contains Panel , each Panel has a PictureBox and a Label inside it. When the user selects the "Directional Navigation" mode, he/she is given an option to navigate between PictureBoxes on the Form using the Direction Keys. Please help!



In my WPF Page application, I have trapped the backspace key (just to prevent to application going back) at the page/window level but the TextBox Level I have to allow this key.

I am not sure how to do this.






Looking at the Reactive Extensions for javascript demo on Jeff Van Gogh's blog , I thought I'd give it a try in C#/Winforms, but it doesn't seem to work so well.

I just threw this into the constructor of a form (with the Rx framework installed and referenced):

Observable.Context = SynchronizationContext.Current;
var mousemove = Observable.FromEvent<MouseEventArgs>(this, "MouseMove");
var message = "Time flies like an arrow".ToCharArray();

for(int i = 0; i < message.Length; i++)
    var l = new Label() { Text = message[i].ToString(), AutoSize = true, TextAlign = ContentAlignment.MiddleCenter };
    int closure = i;
        .Delay(closure * 150)
        .Subscribe(e => 
                l.Left = e.EventArgs.X + closure * 15 + 10;
                l.Top = e.EventArgs.Y;

When I move the mouse, the letters seem to get moved in a random order, and if I uncomment the Debug line, I see multiple events for the same letter...

Any ideas? I've tried Throttle, but it doesn't seem to make any difference. Am I just asking too much of WinForms to move all those labels around?


(Cross posted to StackOverflow )



I have a DataGrid that have combobox on cell edit, i have created my own Custom DataGrid, but when i use Right arrow key on my keyboard it moves only once to the next Cell and it doesn't continue to the next cell, but when i use Numpad6 it moves to many cells which what i wanted Right arrow key to do. what can i do to solve this?

Many Thanks for you reply


Hi I'm getting pretty annoyed when I press the down key to scroll down a page.

The map drags the scroll (the page only move half what is normally would) and it change the map position.

I would like the behavior that when the mouse pointer is on the map, it stops page scrolling and repositions the map, but when the mouse pointer is off the map no repositioning occurs.

I know how to set event on the map (mouseover mouseout), but I don't know how to stop/start the mouse scrolling behavior.


I am using the datagridview in an unbound mode.  The SelectMode is set to CellSelect.  The third visible column is read-only.  The others are not.  When the user enters data and presses tab, the focus moves from cell to cell, even to cells that are read-only.  This makes no sense, other than maybe to allow them to copy/paste data from a read-only cell (not sure how common that need really is). 

I have exlored all sorts of work arounds, none of them are pretty.  Seems like a pretty basic need.  

I wonder if this behavior is a bug or done on purpose.  If it is done on purpose, what was the reason for it?  Is there an option on this control that I am not seeing that will prevent the user from navigating to read-only cells?

Any thought are greatly appreciated.


Hi there

I have a weird problem. Ive created a UserControl that can be used to pan and zoom an image but when ever I add the control to a form my arrow keys will not trigger the KeyDown event anymore. If I remove it no problem.

If I try and listen to the KeyDown event on the control itself nothing fires either!

Ive set the KeyPreview property on the for to True.

I'd be happy to supply the code if anyone think they could solve it..



I'm using a Datagridview to display data from a BindingList(Of T) where T is a custom class called User which implements INotifyPropertyChanged. The DGV is used like a listbox - it shows only a single column and on selecting a row it updates some textboxes which are bound to the DGV. See code below for an example.


PrivateSub Initialize()
  'CustomList is derived from BindingList - by now it does not specify any further props, funcs etc or overload anythingDim list As CustomList(Of User) = User.GetUsers

  dgvUser.DataSource = list

  'I only want the dirtyDisplayName property to be shownWhile dgvUser.Columns.Count > 1
    If dgvUser.Columns(0).HeaderText.Equals("dirtyDisplayName") Then

  dgvUser.Columns(0).Width = dgvUser.ClientSize.Width - 3

  txtID.DataBindings.Add("Text", dgvUser.DataSource, "ID")
  txtLoginName.DataBindings.Add("Text", dgvUser.DataSource, "loginName")



I use the rowValidating event to update a changed user with the DB:


PrivateSub dgvUser_RowValidating(ByVal sender AsObject, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles dgvUser.RowValidating
  If e.RowIndex >= 0 And e.RowIndex < dgvUser.RowCount ThenDim user As User = TryCast(dgvUser.Rows(e.RowIndex).DataBoundItem, User)


Updating the DB, automatically refreshing of the display etc works perfectly fine, except for the case when I press the X-Button on the form to close the window. It seems, in this case the RowValidating event does not fire anymore (I tested that with the console output).

So I fetched the formClosed/Closing events (tested both, no difference). Here I can call the SaveToDB method of my User object, however, this introduced a further problem: It seems, the underlying user object gets updated only, when the bound Textbox loses its focus. This is also reflected by the fact that, if I change the the text in txtLoginname the corresponding item in the DGV gets updated only when I click onto the txtID field or if I select another row. So what happens if I change the text and click the X-Button before clicking onto any other UI element is that the DataBoundItem's property of the DGV still has the old value and so I don't update the new value to the DB.

As a workaround, in formClosing I tried to programatically switch to another row or set the focus to the other textbox, but for some reasons that didn't work, either.

Is there any method that forces the databindings to resync or has anyone some further suggestions on how to fix this?

Thanks in advance



There used to be a ToBindingList method which was necessary for doing change tracking when binding the results of an LINQ to Entities query to a winforms datagridview.

Eventually the tobindinglist was removed

Improved DataBinding usability

Now ObjectQuery<T> and EntityCollection<T> implement IListSource which makes databinding more automatic rather than requiring explicit calls to the ToBindingList() method.In fact, since the automatic mechanism is so much better, ToBindingList was removed..

But now that means the autosorting feature of the DataGridView doesn't work.

Is there another way to coerce this without having to do the sorting programmatically if you are using Linq to Entities?

If not, I'll live but it's just that much more explaining I need to do for the type of people who need to use drag & drop databinding.



I am using VS2010 C# for my application and am very new to coding. I am not using the Data Source to access my SQL tables for several reasons, none that I think have anything to do with my problem (of course, I could be wrong!) I am using code-behind to access my SQL data on a separate data access layer (classes that were created in a class library project that are in the same solution, which I access with the USING command as needed on each winform.)

My problem is that my main form in WinForms has a datagridview that fills using a RefreshGridView() method I created that is called from the mainform_Load() method, both of which are on the form itself. I have a second form to add data to the data table and another form to edit that information. When I save new information on those forms and the forms close, the datagridview on my main form is not updating. Because they are separate forms I cannot access the RefreshVehicleGrid() method that I added to my main form, which stays open the entire time. I need to refresh that datagridview each time I save information added by the AddData and EditData forms. I have thought about creating a Refresh Table Button on my main form that you have to press to refresh, but I would really rather it updates automatically. How can I create an event on the other form's closing that triggers another event to refresh the datagridview when they are on separate forms?


I have an int property of a data source (a BindingList) that contains an ARGB value that I use as the BackColor & SelectionBackColor of a cell in a DataGridView column.  I need the cell to not display the value of the int, but to only set the cell's BackColor/SelectionBackColor based on the int value.  I'm trying to use the DataGridView's CellFormatting (below). This does in-fact set the BackColor/SelectionBackColor, but it also displays the text value of the int.

How can I suppress the text display of the int? I've tried setting both the forecolor and backcolor to the same ARGB value, but that causes the forecolor to change to red (can this behaviour be prevented?). If I were to change the LineColor property to a string, could I then set the value to a null string, after I use it in FromArgb?  But can CellFormatting safely modify the value that will be displayed? Would modifying the value cause a recursive call (some of my experiments indicate it does).




  privatevoid MyGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)


            if (e.ColumnIndex == MyGrid_LineColor.Index)


                var dgv = sender asDataGridView;


                if (dgv != null)


                        MyItem i = dgv.Rows[e.RowIndex].DataBoundItem as MyItem;

                        e.CellStyle.BackColor = Color.FromArgb(i.ColorValue);

                        e.CellStyle.SelectionBackColor = Color.FromArgb(i.ColorValue);






While troubleshooting a DataGridView binding problem, I noticed my form's Designer.cs file contains two definitions for each column in a DataGridView ("YAxisGrid"). For example, the first column is named "YAxisGrid_Anchor" and is defined in Designer.cs as:

private System.Windows.Forms.DataGridViewTextBoxColumn YAxisGrid_Anchor;

... and is referenced in various places in the .cs, such as:

this.YAxisGrid_Anchor.DefaultCellStyle = dataGridViewCellStyle3;

this.YAxisGrid_Anchor.Frozen = true;

this.YAxisGrid_Anchor.HeaderText = "Anchor";

this.YAxisGrid_Anchor.Name = "YAxisGrid_Anchor";

this.YAxisGrid_Anchor.ReadOnly = true;

this.YAxisGrid_Anchor.Resizable = System.Windows.Forms.DataGridViewTriState.True;

this.YAxisGrid_Anchor.Width = 10;


But column #1 is ALSO defined as:


  private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;

... and has these references:


 this.dataGridViewTextBoxColumn1.DefaultCellStyle = dataGridViewCellStyle10;

 this.dataGridViewTextBoxColumn1.Frozen = true;

 this.dataGridViewTextBoxColumn1.HeaderText = "Anchor";

 this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";

 this.dataGridViewTextBoxColumn1.ReadOnly = true;

 this.dataGridViewTextBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True;

 this.dataGridViewTextBoxColumn1.Width = 10;


Notice that the HeaderText is the same, as is the width, etc, so it seems the Designer somehow thinks these are the same column. But DefaultCellStyle is set to a different Style, and the Name is different, so in this sense, the Designer thinks it's dealing with different columns.


But here's where it gets really strange...


The columns in a second DataGridView ("XAxisGrid") on the same form aren't defined twice! Here's the first column of that DataGridView:


private System.Windows.Forms.DataGridViewImageColumn XAxisGrid_GoToEnd;


... and its references:


this.XAxisGrid_GoToEnd.DefaultCellStyle = dataGridViewCellStyle7;

this.XAxisGrid_GoToEnd.HeaderText = "GoToEnd";

this.XAxisGrid_GoToEnd.Name = "XAxisGrid_GoToEnd";

this.XAxisGrid_GoToEnd.Resizable = System.Windows.Forms.DataGridViewTriState.True;

this.XAxisGrid_GoToEnd.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;


What is causing the columns in one DataGridView to be duplicated, but not in the other DataGridView? 


BTW: Thinking this was related to my binding problem, I deleted the duplicated column def (dataGridViewTextBoxColumn1, and its references) from the .cs file, and the app runs fine (although it didn't fix my binding problem... that turned out to be something else).  But the Designer later added the duplicate def and references back again!


Anyone else seen this?










Hi guys, your help would be invaluable

What  I want to do is to have a datagridview bound to a dataset (via wizard bla bla bla, which is easy). In that dataset there is a column that recieves, as entries, smallints which represent corresponding strings that come from a predefined, application scope, list (ie. settings.collection.speciallized.stringcollection or something similar, by the way what would be your choice?). 
So, when seeing or editing a row there will be a combo inplace of that column showing the list items but storing the index of the selected item into that row.

To cut a long story short is there a way of having a non database lookup list as a column of a database bound datagridview?

I apologise for my english but if the above seem greeks to you then.... I will keep searching for a solution (I ve spent about 2 weeks , <-oh, comeon!!!)..... on my own....:)

Thanx indeed for your time
Sincerely yours



i have a question about adding an image in datagridview column .and when click on that image a new form is opened with txtboxs and labels contains data of this row.. for eg

lets say my grid look like that Header

EmployeeName | EmployeeTitle | EditEmployee data

hatem              | Developer      | (imageHere)

 sara                | QA                | (imageHere)

i want to know how can place the image in EditEmployeeColumn and when i click on it another form is displayed contains data of tha selected row


I have WinForm client developed using .NET 3.5 SP1/EF/VS2008

I am using Winforms Binding source and binding Array of EF entities. DataGridView is in turn bound to binding source.

In EF Entity (Ex: Employee), I have a property "OfficeID" in database table -> Which mapped to "Office" and "OfficeReference" in "Employee" entity.

I do have valid Office ID assigned to each Employee and I verified that: OfficeReference.EntityKey is valid -> after I got the Array Of Entities in client.

WinForm DataGridView/BindingSource Binding Problem?

   - In DataGridView, I want Office column to show up Office name or Office ID
   - But when I bind data, I see nothing MAINLY for all FK columns/properties in the Entity (Even through their references are correct)

Please let me know what I am missing OR if this is some known issue with WinForms binding with EF entities.


Been digging around the net for a while and haven't found a good example I translate well.


I'm trying to create a multiple forms that each have a datagridview.  When doubleckicked, it opens another form that also contains a datagridview all related row details on the doubleclicked record. 


All of it connected to datatables in a dataset that have the parent-child relationship establish


For me this would go several levels deep, but I'm really just looking for at least one example that would help me see how to do this.  





i am using in ASP.NET Application somtimes the OnInit Event. Is there something similar in WinForms?

Best regards,
Yavuz B.

My Sharepoint and Enterprise 2.0 Blog http://www.starcoder.net
Microsoft Sharepoint Resources & Blogs List

A bound column named "XAXisGrid_LineColor" in my DataGridView has an index of 5. 

But the following event handler code fails, because XAxisGrid_LineColor.Index is returning 0:

privatevoid XAxisGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)DT 




     if (e.ColumnIndex == XAxisGrid_LineColor.Index)   // Index at this point returns 0

          . . .  


I've set breakpoints at every place the column is referenced, and the index is always 5, as it should be, up until the CellFormatting event handler above. And at that point, Index returns 0.

If I hard-code the event handler to compare e.ColumnIndex == 5, it works! Which tells me that the column is really still at index 5, and that the problem is with the Index property not returning the correct value!

When/where does the Index property of a bound column get set?  Could the CellFormatting event be entered before the Index has been set? Or perhaps the columns with index 0 through 4 haven't yet been added to the columns collection (although the designer code appears to be adding all the columns at once, and the column in-question is the sixth one added).  

This was working until a couple of hours back, when I made some unrelated changes (or so I thought!).







I'm trying to generate a calculator, and as one of the features, when a person selects a 3 for example on their keyboard, I want the corresponding on screenbutton to physically depress and release on screen, so they can see the numbers being entered in as they use the keyboard.

I've looked at the PerformClick() method, and while that does call the appropriate click event, I have not been able to have it graphically depress and release the button on screen.

How can I graphically depress the WinForms buttons on a keyboard event.

As an added bonus, it would be nice to be able to have the button depressed on keydown, and stay depressed until keyup.


<< Previous      Next >>

Microsoft   |   Windows   |   Visual Studio   |   Sharepoint   |   Azure