I have two listview controls, each having the same column headers. Listview1 contains the master data table and listview2 has a much smaller set of data that I need to add to the Master in Listview1. I can add this new data to the bottom of the main data in Listview1 using the AddRange option, but I need to add it to the top of the data in Listview1 but cannot see how.
If anyone can help I would appreciate it. Thank you in advance.
Thank you for your comments, which I have taken on board.
Let me add some more detail and some code. The data in Listview2 is a monthly csv file input which I read into the Listview2. The data is a set of details with the first field being the date, the most recent date at the top of data. I package this data as an array and attempt to load in into listview1, the master file, with the exact same fields and date order. Here is the code I have used to load the csv and the code to place the packaged data into Listview1. The only problem with this is, it places the data at the end of the current file in Listview1, so it would be out of sequence, so I am trying to place it at the top of the current file in Listview1.
' load the file into listview with this quick routine.
Dim CSVTest As List(Of String) = New List(Of String)
CSVTest = File.ReadAllLines(ImportDirname).ToList
Dim ColNames As List(Of ColumnHeader) = New List(Of ColumnHeader)
Dim ColumnArray() As String = CSVTest(0).Split(",")
For i = 0 To ColumnArray.Count - 1
ColNames.Add(New ColumnHeader)
ColNames(i).Name = ColumnArray(i)
ColNames(i).Text = ColumnArray(i)
Next
ListView2.Columns.AddRange(ColNames.ToArray)
'This adds the rest of the data from the file to the listview.
For I = 1 To CSVTest.Count - 1
Dim col() As String = CSVTest(I).Split(",")
Dim NewLVItem As ListViewItem = New ListViewItem(col(0))
NewLVItem.Name = col(0)
For j = 1 To col.Count - 1
NewLVItem.SubItems.Add(col(j))
Next
ListView2.Items.Add(NewLVItem)
Next (I)
' this adds the range to the bottom of the listview data
' - not what is required. I need it at the top !!!!!
Dim Items(ListView2.Items.Count - 1) As ListViewItem
For i As Integer = 0 To ListView2.Items.Count - 1
Items(i) = CType(ListView2.Items(i).Clone, ListViewItem)
Next
ListView1.Items.AddRange(Items)
Again if anyone can help I would be grateful.
Try Something Like This
With lst1. Items.**Insert**(0, "Sample", 0)
.SubItems.Add(2)
.SubItems.Add(3)
.SubItems.Add(4)
.SubItems.Add(5)
.SubItems.Add(6)
.SubItems.Add(listDownload.Count - 1)
End With
Hope this can help you
Related
I've checked for hours but I can't seem to find anything to help.
I want to loop through tables and columns from a dataset and use the column name in a combobox.items.add() line, however the eventual goal is to fill the combobox from the dataset itself possibly in a combobox.datasource line.
The first problem is that I can't get the code correct to setup the combobox control where it allows me to use .items.add("") and in extension .datasource
Error Message = "Object reference not set to an instance of an object"
dstcopt is the dataset from a oledbDataAdapter .fill(dstcopt,"table") line (which returns correct values)
tc_opt is a tab name on a tab control where the comboboxes are
For Each dstable In dstcopt.Tables
For Each dscolumn In dstable.Columns
Dim colName As String = dscolumn.ToString
MsgBox(colName) 'This retuns "aantigen"
Dim cb As ComboBox = Me.tc_opt.Controls("cb_" & colName)
cb.Items.Add(colName)
'cb_aantigen.DataSource = dstcopt.Tables(dstable.ToString)
'cb_aantigen.DisplayMember = "aantigen"
'cb_atarget.DataSource = dstcopt.Tables(dstable.ToString)
'cb_atarget.DisplayMember = "atarget"
Next
Next
The second problem comes when I do it manually (which works) using the exact combobox names cb_aantigen and cb_atarget as seen in the comments.
The problem is that once the form is loaded and the cb's are filled with the correct values, I can't change the value in any single cb individually, when I change one value it changes them all (there is 15 comboboxes in total) I know this is down to using a dataset, but I don't know away to 'unlink them from each other or the dataset'
Not sure if I need to split this into 2 questions, but help on either problem would be appreciated.
EDIT:
After looking at only this section of code for a day. This is what I have come up with to tackle both the problems at once.
The combobox control not working was down to using a tab tc_opt instead of a groupbox gp_anti
The issue with splitting the dataset up into individual comboboxes, I've worked around by taking the value of each cell in the database and adding it separately, probably a better way to do it though
For Each dstable As DataTable In dstcopt.Tables
For Each dscolumn As DataColumn In dstable.Columns
Dim colName As String = dscolumn.ToString
Dim cb(2) As ComboBox
cb(0) = CType(Me.gp_anti.Controls("cb_" & colName), ComboBox)
cb(1) = CType(Me.gp_rec.Controls("cb_" & colName), ComboBox)
cb(2) = CType(Me.gp_nat.Controls("cb_" & colName), ComboBox)
For icb = 0 To cb.Count - 1
If Not (IsNothing(cb(icb))) Then
For irow = 0 To dstable.Rows.Count - 1
If dstable.Rows(irow)(colName).ToString <> Nothing Then
Dim icbitemdupe As Boolean = False
If cb(icb).Items.Contains(dstable.Rows(irow)(colName).ToString) Then
icbitemdupe = True
End If
If icbitemdupe = False Then
cb(icb).Items.Add(dstable.Rows(irow)(colName).ToString)
End If
End If
Next
End If
Next
Next
Next
I have a problem where when I add a subitem to the listview all the subitems go out to each of the columns, what I am trying to do is have 4 columns with the results going vertically down each column, I am going to post the code I am using for 1 of the columns so as not to have too much crap on the page here.
Dim source As String = (New Net.WebClient).DownloadString("http://arma.newagerp.com/bb.php")
ListView1.Columns.Add("Deaths")
Dim formula2 As String = "<td><div class='deaths'>([^<]*)</td></div>"
Dim item2 As New ListViewItem("item2", 1)
For Each item As Match In (New Regex(formula2)).Matches(source)
item2.SubItems.Add(item.Groups(1).Value)
Next
ListView1.Items.AddRange(New ListViewItem() {item2})
if you want more code just tell me but this is working and its just the same for the other 3, the other 3 are just player names, score and time in the same listview.
If i undrstand your question right, you want to add next row after passing the value to all four column? if this is right then have a look example code below.
While (Condition)
Dim objItem As ListViewItem
objItem = lv_Details.Items.Add("")
With objItem
.SubItems.Add("")
.SubItems.Add("")
.SubItems.Add("")
.SubItems.Add("")
End With
End While
Hope this will help. :)
Imported data from CSV to datagridview has header in first row, I could hide that row and name header for every column, problem is that data table has 68 columns. Is it possible to make first row header without having to do that manually for every single column?
Your datagrid should have taken all column names from CSV, if not then you need to have a look at this great article. It will help you a lot. This is the link.
After experimenting and help from user: ooopsoft :
Dim TextFieldParser1 As New Microsoft.VisualBasic.FileIO.TextFieldParser(receiveStream)
TextFieldParser1.Delimiters = New String() {","}
Dim newline() As String = TextFieldParser1.ReadFields()
While Not TextFieldParser1.EndOfData
Dim Row1 As String() = TextFieldParser1.ReadFields()
If DataGridView1.Columns.Count = 0 AndAlso Row1.Count > 0 Then
Dim i As Integer
For i = 0 To Row1.Count - 1
DataGridView1.Columns.Add(newline(i), newline(i))
Next
End If
End While
I have a scrolling datagridview that dyanmically changes it's number of columns and rows. I'm looking for a way to export the datagridview as it is when the user clicks a button. I want it to export as something that cannot be edited (so not excel file). I've tried using iTextSharp to export as pdf and can't seem to come up with a dynamically changing loop that would suit it. Also, I haven't been able to find any sample code using iTextSharp that included also exporting row headers along with column headers. I've also tried one solution (that I can't seem to find at the moment) on the microsoft forums that takes advantage of a the add-on functionality of Excel to write to PDF after the datagridview contents are exported to it. The problem I have with that is it creates way to many pages as well as still shows rows that have been hidden or deleted from the datagridveiw. Any idea of how I can accomplish this feat?
I'll include two pictures to show the way in which the datagridview is dynamically populated and changes
It can have up to 66 rows and 12 columns (not including row or column headers)
You can use EPPlus to create an password-protected (locked) excel file that can be read, but not edited. I can show you how to start from a situation like this:
and get a protected file like this:
First you must download and include the EPPlus Library in your project. Don't forget to check the great EPPlusSamples Project
Then you need a method to extract your DataGridView VISIBLE data (you don't want the invisible column to be exported). I did it using a 2d array. This function accept a DataGridView parameter and returns a 2d array:
Function GetDataGridView2DArray(ByVal dataGridView As DataGridView) As String(,)
'Save list of visible columns
Dim nrVisibleColumns = (From c As DataGridViewColumn In DataGridView1.Columns
Where c.Visible
Select c).ToList()
'create 2d-array to store values, dimensions given by number of rows and visible columns
Dim dgvArray(nrVisibleColumns.Count, DataGridView1.Rows.Count) As String
'create the first row with Column Headers text
For Each col As DataGridViewColumn In nrVisibleColumns
dgvArray(col.Index + 1, 0) = col.HeaderText
Next
'create Rows, including Row Header text
For Each row As DataGridViewRow In DataGridView1.Rows
Dim rowNumber = row.Index + 1
dgvArray(0, rowNumber) = DataGridView1.Rows(row.Index).HeaderCell.Value 'save rowheader cell value
For Each col As DataGridViewColumn In nrVisibleColumns
dgvArray(col.Index + 1, rowNumber) = DataGridView1(col.Index, row.Index).Value
Next
Next
Return dgvArray
End Function
Now that you have your array you can create an Excel File and fill it with data. Plus, before saving, we'll lock it with a password to prevent user editing.
Private Sub CreateXls()
Dim fi = New FileInfo("C:\temp\output.xlsx")
Dim package As New ExcelPackage()
Dim ws = package.Workbook.Worksheets.Add("Dgv Output") 'create sheet
'get array of datagridview data
Dim dataArray = GetDataGridView2DArray(DataGridView1)
'loop my 2d array and fill my excel file
For iColumn As Integer = dataArray.GetLowerBound(0) To dataArray.GetUpperBound(0)
For iRow As Integer = dataArray.GetLowerBound(1) To dataArray.GetUpperBound(1)
ws.Cells(iRow + 1, iColumn + 1).Value = dataArray(iColumn, iRow)
ws.Cells(iRow + 1, iColumn + 1).Style.Locked = True 'lock the cell
Next
Next
ws.Cells.AutoFitColumns() 'resize columns to fit
ws.Protection.AllowFormatColumns = True 'let user resize columns if he wants
ws.Protection.SetPassword("1") 'protect the sheet from editing
package.SaveAs(fi) 'save file
End Sub
Now you should be able to easily export your dynamic DataGridView with one click.
This is My Coding Tested And Output is Perfect :
Dim ExcelApp As Object, ExcelBook As Object
Dim ExcelSheet As Object
Dim i As Integer
Dim j As Integer
'create object of excel
ExcelApp = CreateObject("Excel.Application")
ExcelBook = ExcelApp.WorkBooks.Add
ExcelSheet = ExcelBook.WorkSheets(1)
With ExcelSheet
For Each col As DataGridViewColumn In Me.DataGridView1.Columns
ExcelSheet.Cells(1, col.Index + 1) = col.HeaderText.ToString
For i = 1 To Me.DataGridView1.RowCount
ExcelSheet.cells(i + 1, 1) = Me.DataGridView1.Rows(i - 1).Cells("First Column Name").Value
For j = 1 To DataGridView1.Columns.Count - 1
ExcelSheet.cells(i + 1, j + 1) = DataGridView1.Rows(i - 1).Cells(j).Value
Next
Next
Next
End With
ExcelApp.Visible = True
ExcelSheet = Nothing
ExcelBook = Nothing
ExcelApp = Nothing
I created a custom GridView (actually a RadGrid) which does roughly the following.
Initialize GridView formatting
Setup Columns (depending on type of data to be displayed)
Populate the rows
When Instantiating this GridView, and adding it to my page, I want the first column to contain a "rowspan" attribute on the first row of repeated, but similar data. The "rowspan" value should be equal to the number of similar rows following it. In this way I hope to make the final view cleaner.
The logic for this, I figure, should take place while populating the rows. Initially I add rows to a DataTable and then bind it to the GridView as the final step.
Here's the general logic I was attempting, but it didn't work for me. What am I doing wrong?
Dim dt As New DataTable() 'Has three default columns
For Each d In Documents 'MAIN ITEM (First Column Data)
Dim rowspan As Integer
rowspan = 0
For Each f In Files
If rowspan = 0 Then
Me.dt.Rows.Add(New Object() {d.Title, f.Language, f.FileSize})
'THIS DOESN'T WORK!
Me.dt.Columns(0).ExtendedProperties.Item("rowspan") = rowspan.ToString()
Else
Me.dt.Rows.Add(New Object() {Nothing, f.Language, f.FileSize})
End If
rowspan += 1
Next
Next
Also keep in mind that the this is dumped into a DataView which is sorted by the first column, so I would imagine it must actually be sorted first, then somehow count the rows for each "like" first column, then set the "rowspan" value for the first row of that column equal to the number of rows belonging to it.
Does this make sense? Here is an ideal example of what I would like to accomplish in the layout:
Try this.
Protected Sub DemoGrid_PreRender(sender As Object, e As System.EventArgs) Handles DemoGrid.PreRender
MergeRowsWithSameContent(sender)
End Sub
Public Sub MergeRowsWithSameContent(gvw As GridView)
For rowIndex As Integer = gvw.Rows.Count - 2 To 0 Step -1
Dim row As GridViewRow = gvw.Rows(rowIndex)
Dim previousRow As GridViewRow = gvw.Rows(rowIndex + 1)
For i As Integer = 0 To row.Cells.Count - 1
If row.Cells(i).Text = previousRow.Cells(i).Text Then
row.Cells(i).RowSpan = If(previousRow.Cells(i).RowSpan < 2, 2, previousRow.Cells(i).RowSpan + 1)
previousRow.Cells(i).Visible = False
End If
Next
Next
End Sub
P.S: Shameless port of this wonderful code I have been using for years.