Well I have no idea what you are doing to get a null reference exception if you have what I do. I don't know what your asp markup is for your page or what else you have in there that might be causing your null reference exception.
I don't usually do this because most people (including myself) either can't download sample projects or do not like to download attached example projects, but I have attached a sample project for you to grab.
Anyways, for those who cannot download the sample project I'm going to post the content of the project here.
This is the metals.csv file (located in the root of the project structure):
- 9 carat gold,11.87
-
18 carat gold,23.73
-
Silver,0.49
-
Platinum,27.52
And this is the rates.csv file, also located in the root of my project structure:
- USD,1.15325238
-
EUR,1.4218
-
GBP,1.80402381
(Please note that I am Canadian, so I am 'assuming' the base cost is in Canadian dollars and the other exchange rates are based off the exchange rate with the Canadian dollar as of end of day yesterday)
My Metal class is as follows:
-
Public Class Metal
-
Private _name As String
-
Private _basePriceInGrams As Double
-
Private _amountInGrams As Double
-
-
Private _usdRate As Double
-
Private _euroRate As Double
-
Private _gbpRate As Double
-
-
Public Property Name() As String
-
Get
-
Return _name
-
End Get
-
Set(ByVal value As String)
-
_name = value
-
End Set
-
End Property
-
Public Property BasePriceInGrams() As Double
-
Get
-
Return _basePriceInGrams
-
End Get
-
Set(ByVal value As Double)
-
_basePriceInGrams = value
-
End Set
-
End Property
-
Public Property AmountInGrams() As Double
-
Get
-
Return _amountInGrams
-
End Get
-
Set(ByVal value As Double)
-
_amountInGrams = value
-
End Set
-
End Property
-
-
Public Property UsdRate() As Double
-
Get
-
Return _usdRate
-
End Get
-
Set(ByVal value As Double)
-
_usdRate = value
-
End Set
-
End Property
-
Public Property EuroRate() As Double
-
Get
-
Return _euroRate
-
End Get
-
Set(ByVal value As Double)
-
_euroRate = value
-
End Set
-
End Property
-
Public Property GBPRate() As Double
-
Get
-
Return _gbpRate
-
End Get
-
Set(ByVal value As Double)
-
_gbpRate = value
-
End Set
-
End Property
-
-
-
Public ReadOnly Property CanadianCost() As Double
-
Get
-
Return BasePriceInGrams * AmountInGrams
-
End Get
-
End Property
-
Public ReadOnly Property USACost() As Double
-
Get
-
Return BasePriceInGrams * AmountInGrams * UsdRate
-
End Get
-
End Property
-
Public ReadOnly Property EUROCost() As Double
-
Get
-
Return BasePriceInGrams * AmountInGrams * EuroRate
-
End Get
-
End Property
-
Public ReadOnly Property GBPCost() As Double
-
Get
-
Return BasePriceInGrams * AmountInGrams * GBPRate
-
End Get
-
End Property
-
-
-
-
Public Sub New(ByVal metalName As String, ByVal basePrice As Double)
-
Me.Name = metalName
-
Me.BasePriceInGrams = basePrice
-
Me.AmountInGrams = 10 ' defaulting to 10 grams
-
End Sub
-
End Class
Notice how my Metal class now has properties that let me get and set the exchange rates?
Notice how the Metal class also has properties that return the cost of each metal by using the exchange rates? These properties do all of the calculations so that the GridView can display them in the table.
Recall that the GridView, by default, will display all Public Properties as column headers in the table displayed on the screen. If you don't want something to display in the Grid (say what the exchange rates are) you have to do something to fix that.
Some options to only display the Properties that you want are to:
- Change the scope of the property that you want to hide to "Friend" or "Private" but if you use private you will have to find a different way to set the values
- Change the Properties in to methods (Subs/Functions) because methods are not displayed in grids
- Not depend on the the default behaviour of the GridView and add the specific columns that you want to display
All of this information and MUCH more is in the links that I previously posted about the GridView control.
In my project, there is only one .aspx page in the project called "Default.aspx"
The following is the ASP markup for the Default.aspx file:
-
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
-
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
<html xmlns="http://www.w3.org/1999/xhtml">
-
<head runat="server">
-
<title></title>
-
</head>
-
<body>
-
<form id="form1" runat="server">
-
<div>
-
<asp:GridView ID="GridView1" runat="server" />
-
</div>
-
</form>
-
</body>
-
</html>
And the following is the .vb server-side code for the Default.aspx.vb file:
- Imports System
-
Imports System.IO
-
Imports System.Collections.Generic
-
-
Partial Class _Default
-
Inherits System.Web.UI.Page
-
-
Protected Sub form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles form1.Load
-
Dim metalsSource As New List(Of Metal) 'Will be used as the source for the GridView
-
-
-
If File.Exists(Server.MapPath("~/metals.csv")) Then 'Checking if the file exists before accessing it
-
Dim metalsFileLines As String() = File.ReadAllLines(Server.MapPath("~/metals.csv")) 'Retrieving all lines from file
-
For i As Integer = 0 To metalsFileLines.Length - 1 'Looping through the file lines to retrieve the content from them and populate the Metal objects with data
-
Dim metalLineContent As String() = metalaFileLines(i).Split(",") 'Retrieving the content from the line
-
If metalLineContent.Length = 2 Then 'Checking the length of the content to ensure that it is what we expect it to be before accessing the content to avoid errors/crashing
-
metalsSource.Add(New Metal(metalLineContent(0), CType(metalLineContent(1), Double))) 'Creating a new Metal object, populated with the data from the file, and adding it to the list which is the source for the grid
-
End If
-
Next
-
End If
-
-
If File.Exists(Server.MapPath("~/rates.csv")) Then 'Checking if the file exists before accessing it
-
Dim exchangeRateFileLines As String() = File.ReadAllLines(Server.MapPath("~/rates.csv")) 'Retrieving all lines from file
-
For i As Integer = 0 To exchangeRateFileLines.Length - 1 'Looping through the file lines to retrieve the content from them and populate the Metal objects with data
-
Dim exchangeRateLineContent As String() = exchangeRateFileLines(i).Split(",") 'Retrieving the content from the line
-
If exchangeRateLineContent.Length = 2 Then 'Checking the length of the content to ensure that it is what we expect it to be before accessing the content to avoid errors/crashing
-
For Each m In metalsSource
-
Select Case exchangeRateLineContent(0)
-
Case "USD"
-
m.UsdRate = CType(exchangeRateLineContent(1), Double)
-
Case "EUR"
-
m.EuroRate = CType(exchangeRateLineContent(1), Double)
-
Case "GBP"
-
m.GBPRate = CType(exchangeRateLineContent(1), Double)
-
End Select
-
Next
-
End If
-
Next
-
End If
-
-
GridView1.DataSource = metalsSource 'Setting the source of the GridView
-
GridView1.DataBind() 'Binding to the source
-
End Sub
-
End Class
Notice how I am creating Metal object instances based on what I retrieve from the metal.csv file.
Also notice how I am populating the Metal object instances with the exchange rates from the rates.csv file.
I have no errors when I run my code.
Usually the experts here will work with your current solution to find the best answers based on what you provide. Everyone's coding styles, concepts, approaches, and ways-of-thinking are different.
With that in mind, if you want to achieve the same thing using DataTables as an exercise we can look into what you would need to do to achieve that.
In particular, because DataTables do not have functionality that will do things like "apply an exchange rate", you would have to do the calculations when you retrieve the data from the files to store into the DataTable at the time of population... or you would have to change the GridView so that it does not use the default column-generation behaviour to create your own Template Columns that use ASP calls to do the calculations upon binding to the data to display it... or you would have to over write the row data binding events to do calculations at that point.
Once you try this out post back here and I will help you to understand anything that is confusing about it.
-Frinny