How can I copy object types in VB.NET? - asp.net

I am building an ASP.NET application that needs dynamic tables. That's another issue that I've already posted about (and gotten a pretty good response!). Now, I'm running into another issue - I want to add new rows to my table, but given that I will have 10-12 tables on one page, each containing different objects in their rows (text boxes, check boxes, etc.) I need a way of simply generically adding a new row that has the same objects as the first row in the table. Here's my code:
Private Sub AddTableRow(ByRef originalTable As System.Web.UI.WebControls.Table)
Dim originalRow As System.Web.UI.WebControls.TableRow = originalTable.Rows(1)
Dim insertingRow As New System.Web.UI.WebControls.TableRow
Dim insertingCells(originalRow.Cells.Count) As System.Web.UI.WebControls.TableCell
Dim index As Integer = 0
For Each cell As System.Web.UI.WebControls.TableCell In originalRow.Cells
insertingCells(index) = New System.Web.UI.WebControls.TableCell
insertingCells(index).Controls.Add(cell.Controls.Item(0))
index += 1
Next
insertingRow.Cells.AddRange(insertingCells)
originalTable.Rows.Add(insertingRow)
End Sub
But I'm getting a null reference exception at the second to last line,
insertingRow.Cells.AddRange(insertingCells)
...and I can't figure out why. Is it because the contents of each cell are not being initialized with a new object? If so, how would I get around this?
Thanks!
EDIT:
The inside of my for loop now looks like this -
For Each cell As System.Web.UI.WebControls.TableCell In originalRow.Cells
Dim addedContent As New Object
Dim underlyingType As Type = cell.Controls.Item(0).GetType
addedContent = Convert.ChangeType(cell.Controls.Item(0), underlyingType)
insertingCells(index) = New System.Web.UI.WebControls.TableCell
insertingCells(index).Controls.Add(addedContent)
index += 1
Next
Stepping through with a debugger, I see that this strategy is working - but the additional table row still doesn't appear...and still does when I do this statically.

I think your culprit may be this line:
Dim insertingCells(originalRow.Cells.Count) As TableCell
Confusingly, the number you specify in an array declaration in VB.NET is the upper bound, not the number of elements. So Dim ints(10) As Integer will create an Integer() array with eleven elements, not ten (10 will be the highest index of the array).
Try this instead:
Dim insertingCells(originalRow.Cells.Count - 1) As TableCell

Related

Inserting class property in list through foreach loop in vb.net

I am trying to insert class property in list through foreach loop in VB.NET.
Dim objCoInsurers As List(Of CoInsurer)
CoInsurer class consist of 5 properties
Below there is the code where class properties are inserted in my list
objCoInsurers = New List(Of CoInsurer)
Dim oCoInsurer As New CoInsurer
For Each row As GridViewRow In grdCoInsurance.Rows
Dim lblCoInsurerID = DirectCast(row.FindControl("lblCoInsurerID"), Label)
Dim textCoInsurerID As String = lblCoInsurerID.Text
Dim lblCoInsurerName = DirectCast(row.FindControl("lblCoInsurerName"), Label)
Dim CoInsurerName As String = lblCoInsurerName.Text
oCoInsurer.InsurerID = lblCoInsurerID.Text
oCoInsurer.InsurerName = lblCoInsurerName.Text
objCoInsurers.Add(oCoInsurer)
Next
The issue is when two list containing same value, the first list overwrite the second one, if row count is 2 in gridview or more
Consider this. Let's say that you want to add people to a list using pen and paper. I present myself to you wearing a blue shirt and you write down my name. I then take off my blue shirt and put on a red shirt and present myself to you and you write down my name. I then take off my red shirt and put on a green shirt and present myself to you and you write down my name. How many names do you have on the list? How many people do those names correspond to? What colour shirt do the people those names correspond to have on?
Given that OOP is based on the behaviour of real-world objects, think about what your code actually does. How many ColInsurer objects does your code create? Only one, right? It doesn't matter how many different colour shirts you put on that object and how many times you add it to the list, there's still only one object so it can only be wearing one shirt at a time. At the end of your loop, every item in the list refers to the same object and that object will have whatever property values you set last.
If you want to add multiple distinct objects to the list then you actually have to create multiple distinct objects. That means moving the creation of the object inside the loop, so it happens every iteration. You create a new object, set its properties and then add it to the list:
For Each row As GridViewRow In grdCoInsurance.Rows
Dim oCoInsurer As New CoInsurer
I am guessing your class looks something like this.
Public Class CoInsurer
Public Property InsurerID As String
Public Property InsurerName As String
End Class
I am wondering if InsurerID is a String and not an Integer or Long. If it is a number, be sure to surround the assignment value in the loop with CInt() or CLng()
I got rid of some of the unneeded variables. As jmcilhinney explained, you need to create a new instance of CoInsurer for every iteration of your loop.
Private Sub OPCode()
For Each row As GridViewRow In grdCoInsurance.Rows
Dim oCoInsurer As New CoInsurer
oCoInsurer.InsurerID = DirectCast(row.FindControl("lblCoInsurerID"), Label).Text
oCoInsurer.InsurerName = DirectCast(row.FindControl("lblCoInsurerName"), Label).Text
objCoInsurers.Add(oCoInsurer)
Next
End Sub

Excel column values being appended as rows instead of columns into datatable

I have an Excel file which I need to read through and extract particular values of a certain range into a datatable so I can then save that data into a table in a database.
Whilst debugging, on every loop I check the datatable visualizer to see what's going on and I find that I'm appending values of a different row, to the same row. Example in photo.
SamplePhoto
Here is the code responsible for that action.(Surrounded in a Try-Catch)
Using excel As New ExcelPackage (ulTarget.PostedFile.InputStream)
Dim _worksheet = excel.Workbook.Worksheets.First()
Dim _hasHeader = True
For Each cell In _worksheet.Cells(1,2,147,4)
_dataTable.Columns.Add(If(_hasHeader, cell.Value, String.Format("{0}", cell.Start.Column)))
If _worksheet.Cells.Value Is Nothing Then
Continue For
Next
Assume that the range 1,2,147,4 is correct as the data going into the datatable is correct, the row seperation is simply the problem. _dataTable is my DataTable (obvious I know but nothing bad in clarifying it) and _hasHeader is set to True because the Excel worksheet being uploaded has headers and I don't want them being put into the DataTable because the data will all end up in a table in SQL Server where appropriate column names exist.
Also ulTarget is my File uploader. I am using EPPlus most recent version for this.
Anybody have any suggestions as to how I can seperate the data into rows as per the example in the photo above? Happy to make any clarifications if needed.
Added the horizontal range of the columns without headers and read each cell row by row.
Using excel As New ExcelPackage(ulTargetFile.PostedFile.InputStream)
'Add the columns'
Dim _worksheet = excel.Workbook.Worksheets.First()
Dim _hasHeader As Boolean = False
For Each col In _worksheet.Cells("B1:D1")
_dataTable.Columns.Add(If(_hasHeader, Nothing, col.Value))
String.Format("{0}", col.Start.Column)
Next
'Add the rows'
For rowNumber As Integer = 1 To 147
Dim worksheetRow = _worksheet.Cells(rowNumber, 2, rowNumber, 4)
Dim row As DataRow = _dataTable.Rows.Add()
For Each cell In worksheetRow
row(cell.Start.Column - 2) = cell.Value
Next
Next

ASP VB NET List(of T) find method failing in a for each loop

Good morning stackers!
I'm designing a massive update page. Here are the general steps:
I have a class called item which has two properties: Equipment number and new due date.
I have a textbox where i paste values from Excel, the values consist of two columns divided by a vbtab character: the columns are an equipment number and a new due date
A button is clicked and the values from textbox are parsed into a list(of item) and the equipment master builds a string for an SQL criteria for a commandtext.
The command fills a dataset from a database which gets equipment number and current due date.
I add manually a column to the dataset (new due date)
I iterate over the rows of the dataset, and i use the list(of item) find method matching equipment from the list and from the database to get a new due date from the textbox parsed values.
Everything is going well, except that when using the find method for more than 1 row in the dataset, the method fails:
Here is the code from point 5 and 6:
da.Fill(ds, "Equipments")
dt = ds.Tables(0)
ds.Tables(0).Columns.Add("column_1", Type.GetType("System.DateTime"))
Dim rw As DataRow
For Each rw In ds.Tables(0).Rows
Dim strsearch As String = rw(0).ToString
Dim fequnumb As item = myItemList.Find(Function(p) p.EquipNumber = strsearch)
rw(2) = fequnumb.DueDate <- Error occurs here
Next
Again, if instead of ftechid.DueDate I put a static value like Today()the code runs fine for the loop and fills correctly the gridview, but if i leave the ftechid.DueDate then an error is thrown after the first row:
Object reference not set to an instance of an object.
Any help is very much appreciated as to how to use the find method inside a for..each loop
If the Find function cannot match the string requested it returns Nothing and then you cannot set the due date from a variable that is Nothing. If this is a condition expected from the input then you need to protect the assignment to the new column with something like this.
For Each rw In ds.Tables(0).Rows
Dim strsearch As String = rw(0).ToString
Dim fequnumb As item = myItemList.FirstOrDefault(Function(p) p.EquipNumber = strsearch)
if fequnumb IsNot Nothing Then
rw(2) = fequnumb.DueDate <- Error occurs here
End if
Next
If this is not supposed to happen then you need to check your inputs

Creating ASP.NET table header row

I don't know why this isn't working. I'm trying to create a table header section from the back end code, but everything is going into tbody.
Dim output As New Web.UI.WebControls.Table
'Create the header row
Dim hRow As New Web.UI.WebControls.TableHeaderRow
hRow.TableSection = Web.UI.WebControls.TableRowSection.TableHeader
hRow.Controls.Add(New Web.UI.WebControls.TableHeaderCell)
For Each d As GridDate In Dates
Dim hCell As New Web.UI.WebControls.TableHeaderCell
hCell.Text = d.Value
hRow.Controls.Add(hCell)
Next
output.Controls.Add(hRow)
The result is everything under tbody despite creating a header row and setting the section property to header. What am I doing wrong?
There was an error in the code I posted. In the last line of my code I was appending the new row to the controls collection:
output.Controls.Add(hRow)
Don't do this. It seems to bypass some of the properties unique to ASP.NET TableRows in final rending. In this case, it was ignoring the TableSection property despite being set correctly. You should append rows to the Rows collection instead:
output.Rows.Add(hRow)
Try this
Dim output As New Table
Dim hRow As New TableHeaderRow
For Each d As GridDate In Dates
Dim hCell As New TableHeaderCell
hCell.Text = d.Value
hCell.Scope = TableHeaderScope.Column
hRow.Cells.Add(hCell)
Next
output.Rows.Add(hRow)
This worked for me

Get cell value from specified column in a Gridview upon "RowUpdating" Event ASP.NET/VB

What i want to do is te following... i have a gridview that loads the data from a SQL server, i have the e.NewValue and e.oldValue to determine which data was being modified/updated but i need to get the unique record ID which is store in "ID_ControlCharts" column
So, can you provide a code snippet/brief explanation in how to get the value from "ID_controlCharts" already filled by the gridview when i updated 1 cell (e.new/old)???
Note: The index is not what i needed since the row can be deleted and the reference to that row is now lost, so since the "ID_controlCharts" is filled automatically by SQL server key, its perfect for my situation.
codebehind
If e.Equals("Control_SeqRef_CH") = False Then
Dim oldvalue As String = e.OldValues("Control_SeqRef_CH")
Dim newvalue As String = e.NewValues("Control_SeqRef_CH")
Dim rowindex As Integer = e.RowIndex
Dim IDfromcontrol as integer = ???
MsgBox(oldvalue)
MsgBox(newvalue)
MsgBox(rowindex)
Msgbox(IDfromcontrol)
Else
MsgBox("same")
End If
You have a couple of options:
If the ID_ControlCharts column is in the record, couldn't you fetch it from e.OldValues?
Dim IDfromcontrol = e.OldValues("ID_ControlCharts")
Failing that, if you set ID_ControlCharts as a column for the DataKeyNames property, you should be able to fetch it using the ItemIndex:
Dim IDfromcontrol = GridView1.DataKeys(e.ItemIndex).Values(0)
(This is all from memory, so the syntax may be a little off.)

Resources