autoresizing column header in visual basic datagridview - vb.net

I've been trying to resize the header column in my program as it cuts off an important row label. AutoSizeColumnsMode and AutoResizeColumns() doesn't work. All my attempts so far have lead to the other columns been resized, however not the header column.Image of form
Dim dgv_flightTemplate As New DataGridView
Dim c As Integer = txb_columns.Text
Dim r As Integer = txb_rows.Text
For colcount As Integer = 0 To c - 1
Dim nc As New DataGridViewTextBoxColumn
nc.Name = "Seating Column"
dgv_flightTemplate.Columns.Add(nc)
Next
dgv_flightTemplate.Rows.Add(r)
dgv_flightTemplate.Rows(0).HeaderCell.Value = "A -"
Me.Controls.Add(dgv_flightTemplate)
dgv_flightTemplate.Location = New Point(400, 400)
dgv_flightTemplate.AllowUserToAddRows = False
dgv_flightTemplate.AllowUserToDeleteRows = False
dgv_flightTemplate.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
dgv_flightTemplate.AutoResizeColumns()
also note this has to be done programmatically because i am creating the datagridview from the size the user gives
Thanks for any replies,
Taine

Related

Can't Refresh DataGridView on TabControl Page When There are More Columns Added to DataGridView

There is a DataGridView spawned dynamically and a TabControl is assigned as a parent. The DataGridView is populated with random numbers. While there are no problems with headers or cell values, I can't seem to be able to resize the DataGridView on the tab control page when more columns are added dynamically.
Is there an issue with the Parent scoping for the TabControl, that prevents regeneration and display of more columns on the TabControl, once everything is refreshed?
Dim datagridview1 As New DataGridView
Datagridview1.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
Dim dgvColumnHeaderStyle As New DataGridViewCellStyle()
dgvColumnHeaderStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
Datagridview1.ColumnHeadersDefaultCellStyle = dgvColumnHeaderStyle
Datagridview1.AllowUserToAddRows = False
Datagridview1.ScrollBars = ScrollBars.Both
DataGridView1.Font = New System.Drawing.Font("Lucida Sans Typewriter", 8)
For j As Integer = 1 To UBound(columnheaders)
DataGridView1.Columns.Add(columnheaders(j), columnheaders(j))
Next
For j As Integer = 1 To UBound(columnheaders)
DataGridView1.Columns(columnheaders(j)).HeaderText = columnheaders(j)
Next
For i As Integer = 0 To UBound(rowheaders) - 1
Dim n As Integer = DataGridView1.Rows.Add()
For j = 0 To UBound(columnheaders) - 1
DataGridView1.Rows.Item(n).Cells(j).Value = Rnd()
If i Mod 2 = 0 Then DataGridView1.Rows.Item(i).Cells(j).Style.BackColor = Color.White
If i Mod 2 <> 0 Then DataGridView1.Rows.Item(i).Cells(j).Style.BackColor = Color.AliceBlue
Next
Next
Datagridview1.Visible = True
Datagridview1.Height = Me.Height - 100
Datagridview1.Width = Me.Width - TabControl2.Left - 100
Datagridview1.Parent = TabControl2.TabPages(1)
TabControl2.TabPages(1).Refresh()
TabControl2.Refresh()
Datagridview1.Refresh()
RESOLVED: It worked out that any time you programatically add a datagridview to a tabcontrol, if you update (recreate) the datagridview and want to see the new datagridviw on the same tabcontrol page, you have to clear the controls on the tab page. Following gives an example for using a TabControl1 control and page 0, i.e., the first tab:
Me.TabControl1.SelectedTab = TabControl2.TabPages.Item(0)
Me.TabControl1.TabPages(0).Controls.Clear()
Me.TabControl1.TabPages(0).Controls.Add(datagridview1)

How to get child datagrid values

How can I save values in child popup DataGridView?
I am having parent datagridview and child DataGridView in vb.net
Consider I have 2 columns and 2 rows.
When I click 1st column, I will get child DataGridView just near to this cell. Child DataGridView also has 2 rows and 2 columns where I can enter values.
When I click 2nd column, I'll get another new child DataGridView near this cell.
Now if I move back to first column, values I entered are lost. How can I save entered values in popup child window?
Here is my code:
sub cell_click Dim _pointCell As Point = Me.DgV.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Location Dim _pointGrid As Point = DgV.Location Dim _pointLocation As Point _pointLocation.X = _pointCell.X 'width _pointLocation.Y = _pointCell.Y 'height SelectionInGrid() mPopup.Show(DgV.PointToScreen(New Point(_pointLocation.X, _pointLocation.Y))) end sub
Public SelectionInGrid() Dim t1,t2 As New DataGridViewTextBoxColumn() Dim gv As New DataGridView
gv.Columns.Add(t1)
gv.Columns.Add(t2)
gv.Columns(0).HeaderText = "Employee"
gv.Columns(1).HeaderText = "Currency"
gv.Width = t1.Width + t2.Width
Dim mControlHost As ToolStripControlHost = New ToolStripControlHost(gv)
mControlHost.Padding = Padding.Empty
mControlHost.AutoSize = False
mPopup = New ToolStripDropDown()
mPopup.Padding = Padding.Empty
mPopup.Items.Add(mControlHost)
End
sub cell_click
Dim _pointCell As Point = Me.DgV.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Location
Dim _pointGrid As Point = DgV.Location
Dim _pointLocation As Point
_pointLocation.X = _pointCell.X 'width
_pointLocation.Y = _pointCell.Y 'height
SelectionInGrid()
mPopup.Show(DgV.PointToScreen(New Point(_pointLocation.X, _pointLocation.Y)))
end sub
Public SelectionInGrid()
Dim t1,t2 As New DataGridViewTextBoxColumn()
Dim gv As New DataGridView
gv.Columns.Add(t1)
gv.Columns.Add(t2)
gv.Columns(0).HeaderText = "Employee"
gv.Columns(1).HeaderText = "Currency"
gv.Width = t1.Width + t2.Width
Dim mControlHost As ToolStripControlHost = New ToolStripControlHost(gv)
mControlHost.Padding = Padding.Empty
mControlHost.AutoSize = False
mPopup = New ToolStripDropDown()
mPopup.Padding = Padding.Empty
mPopup.Items.Add(mControlHost)
End
The problem lies in the SelectionInGrid Sub which is called every single time you click a cell. In this function you have these lines:
Dim gv As New DataGridView
Dim mControlHost As ToolStripControlHost = New ToolStripControlHost(gv)
mPopup = New ToolStripDropDown()
This means that everytime cell_click runs a new DataGridView, a new ToolStripControlHost and a new ToolStripDropDown are created. To solve this you need to keep track of the different ToolStripDropDowns. For example using a dictionary:
Private PopUps As New Dictionary(Of String, ToolStripDropDown)
sub cell_click
Dim _pointCell As Point = Me.DgV.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Location
Dim _pointGrid As Point = DgV.Location
Dim _pointLocation As Point
_pointLocation.X = _pointCell.X 'width
_pointLocation.Y = _pointCell.Y 'height
If PopUps.ContainsKey(<Parent Selected cell identifyer>) Then
mPopup = PopUps(<Parent Selected cell identifyer>)
Else
SelectionInGrid()
PopUps.Add(<Parent Selected cell identifyer>,mPopup)
End If
mPopup.Show(DgV.PointToScreen(New Point(_pointLocation.X, _pointLocation.Y)))
end sub
I do believe this should work. "Parent Selected cell identifyer" must be something unique from the Parent DGV row/cell that was clicked.

Adding a header row to a datagrid breaks paging

I wonder if anyone ever incurred into this.
I adding a extra row to a datagrid header, in order to provide a common description to a group of columns.
I use the following code, but it creates problems with the pager, I.E. the bottom pager is not in synch with the top one.
Sub dgResults_Item_Created(sender As Object, e As DataGridItemEventArgs)
'http://www.codeproject.com/Articles/16049/Merge-Header-GridView-DataGrid
If (e.Item.ItemType = ListItemType.Header) Then
Dim mTable = DirectCast(dgResults.DataSource, DataView)
If (Not IsNothing(mTable)) Then
Dim colSpan = 4 ' colspan of new header
Dim colCount = mTable.Table.Columns.Count ' add cell at colCount - colSpan
Dim dgitem = New DataGridItem(0, 0, ListItemType.Header)
Dim dgcell1 = New TableCell()
Dim dgcell2 = New TableCell()
dgcell1.ColumnSpan = colCount - colSpan
dgcell2.ColumnSpan = colSpan
dgitem.Cells.Add(dgcell1)
dgitem.Cells.Add(dgcell2)
dgcell2.Text = "Client information"
dgcell2.HorizontalAlign = HorizontalAlign.Center
dgResults.Controls(0).Controls.Add(dgitem)
End If
End If
End Sub 'Item_Created
Probably the best way to go would be using a GridView
http://msdn.microsoft.com/en-us/library/05yye6k9.aspx

Exporting displayed columns in dataGridView to Excel

I may be blind, but this is a little different than the normal export-to-excel. I've created a solution and would like to know if this is the best way. Or even if there is another way to do it.
Background: WinForms, VisualBasic, VS2012, N-Tier (backend is DB2). My DTOs are set up in order of the DB2 tables. My users want to see the fields in a certain order within the DGV AND be able to export the fields in the same order. Users can also rearrange and hide columns. Hidden columns should not be exported.
My solution does do the normal copy from dgv field by field to excel. The difference is that I had to use DataGridViewColumnCollection so that I could utilize DataGridViewElementStates.Visible in order to make sure I'm only exporting visible columns.
Here is the code.
Private Sub ExportToExcelToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExportToExcelToolStripMenuItem.Click
If((dgv.Columns.Count = 0) Or (dgv.Rows.Count = 0)) Then Exit Sub
Dim XlApp = New Excel.Application With {.Visible = True}
xlApp.Workbooks.Add(Excel.XlSheetType.xlWorksheet)
Dim xlWS = xlApp.ActiveSheet
xlWS.Name = "Exported Data"
'Copy visible data from DGV to Excel
Dim columnCollection As DataGridViewColumnCollection = dgv.Columns
Dim currentVisibleColumn AS DataGridViewColumn = columnCollection.GetFirstColumn(DataGridViewElementStates.Visible)
Dim lastColumnExported As DataGridViewColumn = currentVisibleColumn
Dim visibleColumntCount As Integer = columnCollection.GetColumnCount(DataGridViewElementStates.Visible)
'Finally export the data
For c = 1 to VisibleColumnCount
xlWS.Cells(1,c) = currentVisibleColumn.HeaderText
currentVisibleColumn = columnCollection.GetNextColumn(lastColumnExported, DataGridViewElementStates.Visible, DataGridViewElementStates.None)
lastColumnExported = currentVisibleColumn
Next
'Only export visible cells
For r = 0 To dgv.Rows.Count - 1
'Reset values
currentVisibleColumn = columnCollection.GetFirstColumn(DataGridViewElementStates.Visible)
lastColumnExported = currentVisibleColumn
For c = 1 to visibleColumnCount
Dim value = dgv.Rows(r).Cells(currentVisibleColumn.Index).Value
If value <> vbNullString Then
xlWS.Cells(r + 2, c) = value.ToString()
End If
currentVisibleColumn = columnCollection.GetNextColumn(lastColumnExported, DataGridViewElementStates.Visible, DataGridViewElementStates.None)
lastColumnExported = currentVisibleColumn
Next
Next
'Autosize columns in excel
Dim columns = xlWS.UsedRange.Columns
columns.AutoFit()
End Sub
Thank you for your feedback.
Brian.
Theres is more simple way to do that and it is to perform the if statmente at each iteration of the cells copy process. You ask if that column at that index is visible, if it is visible you copy else you skeep that column and take next.

multiple DatagridView Rendering Vb.net

I'm able to add multiple datagridview 1 after another on panel.
by adding code of SysDragon from the same forum
Dim AllDataGrids As List(Of My_custom_DGV)
Dim lastCtrl As Control
AllDataGrids = New List(Of My_custom_DGV)
For j As Int32 = 0 To 3
Dim aDataGridView As New My_custom_DGV()
aDataGridView.for_date = ""
aDataGridView._count = week_count
aDataGridView.Dock = DockStyle.Top
aDataGridView.Dock = DockStyle.Right
aDataGridView.Dock = DockStyle.Left
aDataGridView.Dock = DockStyle.Bottom
AllDataGrids.Add(aDataGridView)
Next j
For i As Integer = 1 To 3
Dim dgv As My_custom_DGV = AllDataGrids(i)
' Dim dgv As DataGridView = AllDataGrids(i)
If dataGrid_Panel.Controls.Count.Equals(0) Then
dgv.Top = DataGridView1.Height + 20
Else
lastCtrl = dataGrid_Panel.Controls(dataGrid_Panel.Controls.Count - 1)
dgv.Top = lastCtrl.Top + lastCtrl.Height + 5
End If
dataGrid_Panel.Controls.Add(dgv)
Next
the problem is that when i scroll in between them then it is looking very bad(i.e. as i scroll,it is repeating the the image on panel again and again). does it render the view again when i Scroll,and may be calling the paint method of datagridview repeatedly. if yes then what is the solution?
Thanks.