Thursday, June 19, 2008

DataGridView control FAQs and Quick Tips

In this post we will discuss some FAQs regarding DataGridView control. I will be (inshaALLAH) updating this post, when I find new FAQ, if you have any question(s) you can contact me on my email address displayed on right side.

Level: Beginner

Introduction:

Q: What is DataGridView control?
Ans: DataGridView control is used to display the data from Data Source (e.g. DataTable) in a Tabular Form i.e. in Columns and Rows like Spreadsheet.

Q: How can I use DataGridView control?
Ans: DataGridView control can be used either by attaching it to some Data Source or without attaching it with any Data Source. You can simply drag and drop the control on form, add columns using Columns Properties or by using Smart Tags, run the program and start using the control just like you use the Excel.

Data Binding:

Q: How can I attach the DataGridView to some Data Source?
Ans: Attaching of DataGridView to some Data Source is called Data Binding. You can bind the DataGridView with DataTable directly or can use a BindingSource.

Q: How to Bind DataGridView to a DataTable Programmatically?
Ans: Use the following code

DataGridView1.DataSource = MyDataTable

Q: How to Bind DataGridView to a DataTable of a DataSet Programmatically?
Ans: Use the following code

DataGridView1.DataSource = MyDataSet
DataGridView1.DataMember = "MyTable"


Q: How to Bind DataGridView to a BindingSource Programmatically?
Ans: Use the following code

DataGridView1.DataSource = MyBindingSource

Q: When I Bind my DataGridView programmatically it automatically generates the Columns, how can I prevent it?
Ans: Set the AutoGenerateColumns Property = False before setting the DataSource

DataGridView1.AutoGenerateColumns = False
DataGridView1.DataSource = Me.BindingSource1


Q: I have added some columns in my DataGridView control and haven't bind it to anything, how can I add rows in it?
Ans: Use the following code

DataGridView1.Rows.Add(5) ' This will ad blank 5 Rows
OR
DataGridView1.Rows.Add("Item in 1st Column", "Item in 2nd Column")

Q: How to make DataGridView Read-only
Ans: Set the following properties,

AllowUserToAddRows = False
AllowUserToDeleteRows = False
ReadOnly = True


Selection:

Q: How can I select all the Columns and Rows (cells) of DataGridView control Programmatically?
Ans: Use the following code

DataGridView1.SelectAll()

Q: I want to change the selection style of DataGridView from single Cell to Full Row
Ans: Use the following code

DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect

Q: How can I copy the Selected Cells onto Clipboard Programmatically?
Ans: Use the following code

My.Computer.Clipboard.SetDataObject(DataGridView1.GetClipboardContent())

Q: How can I Paste the data from Clipboard to DataGridView control?
Ans: See Paste Text in DataGridView Control (Bound with BindingSource)

Q: How can I prevent user to select multiple Cells/Rows? How can I restrict user to select only one cell/row at a time?
Ans: Set the property

DataGridView1.MultiSelect = False

Q: How can I get the current row of DataGridView which is selected?
Ans: Use DataGridView.CurrentRow property. This will be Nothing if no row exists in DataGridView.

Q: How can I get all currently Selected Rows of DataGridView control?
Ans: Use DataGridView.SelectedRows property.

Q: How can I get all currently selected cells of DataGridView control?
Ans: User DataGridView.SelectedCells property.

Q: How can I select DataGridView row programmatically?
Ans: Use the following code:

DataGridView1.Rows(0).Selected = True

Q: How can I change the current row of DataGridView control?
Q: DataGridView control's CurrentRow property is read-only, how can I change the Current Row?
Q: I want to change the focus (dotted border) to some other cell in DataGridView control, programmatically.

Ans: Use CurrentCell property,

DataGridView1.CurrentCell = DataGridView1.Rows(0).Cells(0)

Layout:

Q: I there any way to make all the columns fit in the DataGridView control?
Ans: 2 Ways

i) Set the DataGridView's AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill

OR

ii) Set at least one column's AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill

Formatting:

Q: How can I change the Format of Numeric and Date Values in DataGridView?
Ans: Set the DefaultCellStyle.Format property

E.g.
Column1.DefaultCellStyle.Format = "dd-MMM-yyyy" ' display as 01-Jan-2008
Column2.DefaultCellStyle.Format = "N0" ' only numeric NO decimals


Definitions:

Q: What is Unbound Column in DataGridView control?
Ans: Unbound column is a column added in DataGridView control but NOT bound to any thing i.e. the Column's DataProperptyName Property has NOT been assigned any value.

Column1.DataPropertyName = ""

Q: What is Virtual Mode of DataGridView control?
Ans: When VirtualMode property of DataGridView Control is set to True, then the DataGridView Control is said to be in Virtual Mode. In this mode CellValueNeeded event triggers for Unbound Columns. In the event Handler of this event we provide some value (using e.Value) which then renders that value in cell.

Events:

Q: CellValueNeeded event is NOT being fired/triggered/executed!
Q: CellValueNeeded event is NOT working!

Ans: VirtualMode property of DataGridView control must be True, also CellValueNeeded is only triggered for Unbound Columns. See previous question.

Q: What event occurs when user Double clicks on a Cell in DataGridView control?
Ans: CellDoubleClick event

Q: What is the difference between CellContentClick and CellClick events in DataGridView control?
Ans:

CellContentClick is triggered for
*) DataGridViewLinkColumn
*) DataGridViewButtonColumn
*) DataGridViewCheckBoxColumn
when user click on link, button or checkbox in cell

CellClick event occurs when user clicks on Cell (NOT its contents i.e. link, button or checkbox)

Misc.:

Q: I have a Editable DataGridView control. I want to detect whether current row is the New Row (new row = last row in DataGridView which has a "*" sign in its row header)?
Ans: Use the IsNewRow property of DataGridViewRow

DataGridView1.Rows(0).IsNewRow

Q: When user presses TAB key in DataGridView Control, current cell changes to next cell, I want to suppress this behavior and want to change the Focus to next control, how can I do this?
Ans: Set the property of DataGridView

StandardTab = True

Q: How can I change the default Editing behavior of DataGridView Control?
Ans: Use the EditMode property, values can be:

EditOnEnter = Edit begins immediately when cell gets focus, no need to press F2 or any key
EditOnKeyStroke = Edit begins on Key stroke, NOT on F2
EditOnKeystrokeOrF2 = Edit begins on both F2 or Key stroke
EditOnF2 = Edit begins only on F2
EditProgrammatically = Edit programmatically i.e. you have to call BeginEdit() method

Q: I have bind my DataGridView to the DataTable, one column of this Table does NOT allow NULL, when user tries to enter a NULL value in this column through DataGridView control, an exception occurs but DataGridView automatically handles it and displays a big Dialog Box. How can I suppress it?
Ans: Use the DataError event of DataGridView control. In the handler of this event you can use e.Exception to see which exception is occurred, and can show your own Dialog Box.

Q: I started adding first row in DataGridView control, and then I pressed ESC (to cancel) an exception occurred which unfortunately cannot be handled, why?
Ans: This is a bug confirmed by Microsoft

See the following KB Article

FIX: Error message when you try to press ESC to cancel adding a new row to a DataGridView control in the .NET Framework 2.0: "An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll"

8 comments:

Unknown said...

thanks for this article it is very simple and clear

Arsalan Tamiz said...

Thank you

Anonymous said...

Great article. Thanks

Anonymous said...

Great thanks for the help.

Unknown said...

Any way to prevent datagridview from showing partial rows (due to difference in height of control vs height of rows) like you can with a listbox?

Arsalan Tamiz said...

Hi Joshua,

A simple work-around is,

1) Fix the height of all rows of DataGridView control i.e. Set AllowUserToResizeRows = False.
2) Fix the height of column header i.e. set ColumnHeadersHeightSizeMode = DisableResizing
3) Set the height of column header same as the height of other rows. Normally the default height of other rows is defined in RowTemplate property which is 22
4) Now set the total height of DataGridView according to the number of rows you wish to display, using this formula,
DataGridView1.Height = RowsToDisplay * DataGridView1.RowTemplate.Height + 2

Note that you may need to recalculate the height of DataGridView control again on resize.

Luc said...

Is there an "easy" way to change the selection behavior in a datagridview so that a click on a selected row does not toggle the selection as long as the mouse button is not released, without resorting to a user-defined control with inheritence and method overrides ?

Arsalan Tamiz said...

@Luc I posted your solution,

DataGridView control change Selection on Mouse Up