I am looking into create a dynamic survey as posted in Get User Input From Dynamic Controls but with some different environment.
Below is what i am trying to do:
First when the user click the button, it will populate a dynamic table with radio button for the survey questionnaire inside a placeholder. However, I was unable to get its value (for score calculation) after clicking the submit button.
All the dynamic controls was gone.
Beside i am using an ajax extension (updatePanel) for the development and
I have been look into viewstate but I have no idea with it.
Does anyone have any ideas?
Here i included some of my code:
Page
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="btnTest" runat="server" Text="Take Test" OnClick="btnTest_Click" Visible="False" />
<asp:Label ID="lblTestErrMsg" runat="server"
ForeColor="Red"></asp:Label><br />
<table id="tblTest" runat="server" style="width: 100%">
<tr>
<td>
<asp:PlaceHolder ID="phQuestionnaire" runat="server"></asp:PlaceHolder>
<br />
</td>
</tr>
<tr>
<td>
</td>
</tr>
<tr>
<td>
<asp:Label ID="lblResult" runat="server"></asp:Label></td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
Create Dynamic Table function
*v_dtTable and v_dtTable2 contains the data from database
Private Sub CreateDynamicTable(ByVal v_dtTable As Data.DataTable, ByVal v_dtTable2 As Data.DataTable)
Me.phQuestionnaire.Controls.Clear()
Dim cols As Integer = v_dtTable.Rows.Count + 2
Dim rows As Integer = v_dtTable2.Rows.Count + 1
Dim mid As Integer = v_dtTable.Rows.Count / 2
Dim tbl As Table = New Table()
tbl.ID = "tblQs"
tbl.BorderWidth = 1
tbl.CellPadding = 0
tbl.CellSpacing = 0
tbl.Width = 500
tbl.EnableViewState = True
Me.phQuestionnaire.Controls.Add(tbl)
For i As Integer = 0 To rows - 1
Dim tr As TableRow = New TableRow()
Dim rowCnt As Integer = 1
Dim colCnt As Integer = 0
For j As Integer = 0 To cols - 1
Dim tc As TableCell = New TableCell()
tc.BorderWidth = 1
Dim lbl As Label = New Label()
Dim bol As Boolean = False
If i = 0 Then
If j = 0 Then
tc.Text = "No."
ElseIf j = 1 Then
tc.Text = "Question"
Else
tc.Text = v_dtTable.Rows(j - 2).Item("scoreName")
tc.HorizontalAlign = HorizontalAlign.Center
End If
tc.BackColor = Drawing.Color.DeepSkyBlue
tc.ForeColor = Drawing.Color.White
Else
If v_dtTable2.Rows(i - 1).Item("isHeader") Then
bol = True
tc.Text = v_dtTable2.Rows(i - 1).Item("TestQuestion")
tc.Style("font-weight") = "bold"
ElseIf j = 0 Then
tc.Text = rowCnt
rowCnt += 1
ElseIf j = 1 Then
tc.Text = v_dtTable2.Rows(i - 1).Item("TestQuestion")
Else
Dim rBtn As RadioButton = New RadioButton
rBtn.GroupName = "rBtn" & rowCnt
rBtn.ID = "rBtn_" & rowCnt & "_" & colCnt
rBtn.InputAttributes("value") = v_dtTable.Rows(j - 2).Item("scoreValue")
colCnt += 1
If j = mid + 2 Then
rBtn.Checked = True
End If
tc.Controls.Add(rBtn)
tc.HorizontalAlign = HorizontalAlign.Center
End If
End If
If bol Then
tc.ColumnSpan = cols - 1
tr.Cells.Add(tc)
Exit For
Else
tr.Cells.Add(tc)
End If
Next j
tbl.Rows.Add(tr)
Next i
End Sub
Calculate Score function
Private Sub subCalculateScore()
Dim tblQs As Table = CType(Me.phQuestionnaire.FindControl("tblQs"), Table)
Dim rb As New RadioButton
Dim score As Integer = 0
If Me.phQuestionnaire.FindControl("tblQs") Is Nothing Then
Else
For Each tr As TableRow In tblQs.Rows
For Each tc As TableCell In tr.Cells
For Each c As Control In tc.Controls
If c.GetType.ToString = rb.GetType.ToString Then
Dim rBtn As RadioButton = CType(c, RadioButton)
If rBtn.Checked Then
Dim strScore As String = rBtn.InputAttributes("value")
score += CInt(strScore)
End If
End If
Next
Next
Next
End If
Me.Label1.Text = score
End Sub
View source for the dynamic generated table
<table id="tblQs" cellspacing="0" cellpadding="0" border="0" style="border-width:1px;border-style:solid;width:500px;border-collapse:collapse;"><tr>
<td style="border-width:1px;border-style:solid;"><span>No.</span></td>
<td style="border-width:1px;border-style:solid;"><span>Question</span></td>
<td style="border-width:1px;border-style:solid;"><span>dislike</span></td>
<td style="border-width:1px;border-style:solid;"><span>normal</span></td>
<td style="border-width:1px;border-style:solid;"><span>like</span></td>
<td style="border-width:1px;border-style:solid;"><span>vry likes</span></td></tr><tr>
<td style="border-width:1px;border-style:solid;"><span>1</span></td>
<td style="border-width:1px;border-style:solid;"><span>question 1</span></td>
<td style="border-width:1px;border-style:solid;">
<input id="rBtn_1_0" type="radio" name="rBtn1" value="rBtn_1_0" value="0" /></td>
<td style="border-width:1px;border-style:solid;">
<input id="rBtn_1_1" type="radio" name="rBtn1" value="rBtn_1_1" value="1" /></td>
<td style="border-width:1px;border-style:solid;">
<input id="rBtn_1_2" type="radio" name="rBtn1" value="rBtn_1_2" checked="checked" value="2" /></td>
<td style="border-width:1px;border-style:solid;">
<input id="rBtn_1_3" type="radio" name="rBtn1" value="rBtn_1_3" value="3" /></td></tr></table>
If the names of the generated radio button groups are predictable enough, you could get their values by inspecting the Request.Form collection. Assuming the group names are rBtn1, rBtn2, etc, the post data will look something like rBtn1=6&rBtn2=7. That means you can do this:
Dim i as Integer
Dim score as Integer = 0
For i = 1 To expectedNumRows
score += CInt(Request.Form("rBtn" & i))
Next
This will help you work around the fact that the controls that were generated before no-longer exist. You should poke around in the debugger and inspect the Request.Form collection so you can get familiar with what's in there.
(my apologies if my VB.NET is incorrect; I'm used to C#)
Thank you Jacob for his solution.
I am able to calculate the score by making some modification for the ID assignment.
I added its value at the back of the id since the value generated is the same with the ID as shown in the view source
rBtn.ID = "rBtn[" & rowCnt & "][" & colCnt & "]_" & value (eg. rBtn[1][0]_2 )
Then, i used substring to get and calculate the score as shown in the subCalculateScore function below:
Private Function subCalulateScore() As Integer
Dim score As Integer = 0
Dim expectedNumRows As Integer = Me.qsNum.Text
For i As Integer = 1 To expectedNumRows
Dim strBtn As String = Request.Form("rBtn" & i)
If Not strBtn Is Nothing Then
If strBtn.LastIndexOf("_") <> -1 Then
Dim strScore As String = strBtn.Substring(strBtn.LastIndexOf("_") + 1)
score += CInt(strScore)
End If
End If
Next
Return score
End Function
Haha.. sound like a lousy way to do it :p
Once again, thanks for your help, Jacob.
Always welcome for any other solution ^^
I figured out yesterday that you can actually make your app work like normal by loading the control tree right after the loadviewstateevent is fired. if you override the loadviewstate event, call mybase.loadviewstate and then put your own code to regenerate the controls right after it, the values for those controls will be available on page load. In one of my apps I use a viewstate field to hold the ID or the array info that can be used to recreate those controls.
Protected Overrides Sub LoadViewState(ByVal savedState As Object)
MyBase.LoadViewState(savedState)
If IsPostBack Then
CreateMyControls()
End If
End Sub
Related
I have radio button like below
<dx:ASPxRadioButtonList ID="radClaimType" runat="server" RepeatDirection="Horizontal" AutoPostBack="true" ValueType="System.String" Border-BorderStyle="None">
<Items>
<dx:ListEditItem Text="Expenses" Value="1" />
<dx:ListEditItem Text="Travel" Value="2" />
</Items>
</dx:ASPxRadioButtonList>
How do I select/check the radio button based on the value that I have inserted in database ?
Here is my code behind
Dim dt As New Datatable
Dim strSelect As String = "SELECT claim_type FROM detail_table WHERE id = '30'"
Dim myconn As New clsConnection
Try
myconn.OpenConnection()
myconn.FillDataTable(dt, strSelect)
myconn.CloseConnection()
If dt.Rows.Count > 0 Then
If dt.Rows(0).Item("claim_type") = 1 Then
radClaimType.SelectedIndex = 1
ElseIf dt.Rows(0).Item("claim_type") = 2 Then
radClaimType.SelectedIndex = 2
End If
radClaimType.Enabled = False
End If
Catch ex As Exception
MsgBox("Error")
myconn.CloseConnection()
End Try
The result is like this which is incorrect because the claim_type value for id = '30' is 1 which is Expense. I have debug the code and the value for claim_type is indeed 1 but the radio button does not checked/selected to Expense. How do I correct this ?
You should tag what 3rd party control library you are using here.
Anyway, as a general rule, the asp.net RB-list can be set by "index", starting at 0, or you can set by value.
So, for your code, then this:
radClaimType.SelectedValue = dt.Rows(0).Item("claim_type")
You do NOT want to set by index, since the RB list could have ANY values, and
0 = first one
1 = 2nd one
etc. etc. etc.
So, index starts at 0
but, you want to set the RB by "value", and hence:
radClaimType.SelectedValue = dt.Rows(0).Item("claim_type")
You can check your documentaton for that control (I don't have it).
But, you don't need a "if/then" here. You can set the value of the RB, and it should then select/display the value corectly
so with this:
<asp:RadioButtonList ID="RadioButtonList1" runat="server"
RepeatDirection="Horizontal" AutoPostBack="true" >
<asp:ListItem Value="100">Expenses</asp:ListItem>
<asp:ListItem Value="200">Travel</asp:ListItem>
</asp:RadioButtonList>
Then I can set 0 (first) or 1 (second) using "indexing" like this:
RadioButtonList1.SelectedIndex = 0 ' would select the 100
RadioButtonList1.SelectedIndex = 1 ' would select the 200
Or, by value
RadioButtonList1.SelectedValue = 100 ' would select the first one
The problem I'm having is when a user skips over cycle time, even with the required field validator in place it allows to to still submit and crash the page. I tried setting an initial value but that didn't work.
<div class="col-lg-4" style="text-align: left;">
<label for="txtCycle_Time">Cycle Time (format mm:ss) :</label>
<asp:TextBox ID="txtCycle_Time" MaxLength="5" CssClass="form-control" runat="server"></asp:TextBox>
<ajaxToolkit:MaskedEditExtender ID="txtCycle_Time_MaskedEditExtender" AutoComplete="true" MaskType="Time" AcceptAMPM="false" runat="server" MessageValidatorTip="true" TargetControlID="txtCycle_Time" Mask="99:99" ClearMaskOnLostFocus="false" />
<asp:RequiredFieldValidator ID="txtCycle_Time_RequiredFieldValidator" runat="server" InitialValue="00:00" Text="Please Enter Cycle Time" ControlToValidate="txtCycle_Time" ValidationGroup="Input" Font-Italic="True" ForeColor="Red" />
</div>
Dim Cycle_Time_Sec As Integer = 0
Dim My_Time As String = ""
My_Time = txtCycle_Time.Text
Dim Min As String = My_Time.Substring(0, 2)
Dim Sec As String = My_Time.Substring(3, 2)
Cycle_Time_Sec = Min * 60 + Sec
You could try a server side validation on postback:
Dim Cycle_Time_Sec As Integer = 0
Dim My_Time As String = ""
//Validation here
If txtCycle_Time.Text is null Then return "Please type time value!"
My_Time = txtCycle_Time.Text
Dim Min As String = My_Time.Substring(0, 2)
Dim Sec As String = My_Time.Substring(3, 2)
Cycle_Time_Sec = Min * 60 + Sec
Wrote this to fix the issue, now form works as intended.
If (txtCycle_Time.Text.Trim = "__:__" Or txtCycle_Time.Text.Trim = "__:__ AM"
Or txtCycle_Time.Text.Trim = "__:__ PM") Then ScriptManager.RegisterStartupScript(Me, Me.GetType(), "Cycle_Time_Error", "Cycle_Time_Error();", True)
Exit Sub
End If
In SQL Server, I created a dynamic SQL stored procedure to query for the production record and pivoted in each month
In ASP.net using VB.net, I have a page with a DataGrid to display the query results dynamically using the DataBound method
I have a textbox to change the value of specific cell in the DataGridView like the production order quantity
Problem: when I assigned a value from textbox to the cell of datagridview, there is no change at all.
It just refreshed and get the value of the SQL query from the stored procedure. It always invokes the DataBound method of the DataGrid.
Questions: what is the technique so that I can assign the value to cell of DataGridView which is has data binding to the dynamic SQL Server stored procedure? The thing here is I want to save the changes in the DataGrid to another Table as the transnational.
Here is aspx code:
<%# Page Title="" Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="GeneratePlan.aspx.vb" Inherits="GeneratePlan" %>
<%# Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="cc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<style type="text/css">
.style1
{
width: 55px;
}
.style2
{
width: 7px;
}
</style>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<div>
<table width="100%">
<tr >
<td style="text-align: right;" >
<asp:Button ID="btnSave" runat="server" Text="Save Plan" CssClass="button" /><asp:Button ID="btnExit" runat="server" Text="Exit" CssClass="button" />
</td>
</tr>
<tr>
<td class="tdHeaderSubSection">
<asp:Label ID="lblReq" runat="server" Text=">> Generate Plan"></asp:Label>
</td>
</tr>
</table>
</div>
<div>
<table width ="100%">
<tr>
<td class="style1">
<asp:Label ID="Label3" runat="server" Text="BU"></asp:Label></td>
<td class="style2">::</td>
<td>
<asp:DropDownList ID="ddlBU" CssClass="Data" runat="server" Height="16px"
Width="130px">
</asp:DropDownList>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>
<asp:Button ID="btnGenerate" CssClass="button" runat="server" Text="Generate" />
<asp:Button ID="btnMove" CssClass="button" runat="server"
Text="Move MC#" />
<asp:Label ID="Label4" runat="server" Text="Label"></asp:Label>
</td>
</tr>
<tr>
<td colspan ="3"> <asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager> </td>
</tr>
</table>
</div>
<div id ="planDtl">
<asp:GridView ID="grdPlanDtl" AutoGenerateColumns = "False"
runat="server" Font-Size="10px">
</asp:GridView>
</div>
<div>
</div>
</asp:Content>
Here is the vb.net code:
Protected Sub OnRowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles grdPlanDtl.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ItemCode As New Label()
ItemCode.ID = "ItemCode"
ItemCode.Text = TryCast(e.Row.DataItem, DataRowView).Row("ItemCode").ToString()
e.Row.Cells(1).Controls.Add(ItemCode)
ItemCode.Width = 100
Dim Description As New Label()
Description.ID = "Description"
Description.Text = TryCast(e.Row.DataItem, DataRowView).Row("Description").ToString()
e.Row.Cells(2).Controls.Add(Description)
Description.Width = 200
Dim WH As New Label()
WH.ID = "WH"
WH.Text = TryCast(e.Row.DataItem, DataRowView).Row("WH").ToString()
e.Row.Cells(3).Controls.Add(WH)
e.Row.Cells(3).HorizontalAlign = HorizontalAlign.Center
WH.Width = 10
Dim Customer As New Label()
Customer.ID = "Customer"
Customer.Text = TryCast(e.Row.DataItem, DataRowView).Row("CustName").ToString()
e.Row.Cells(4).Controls.Add(Customer)
Customer.Width = 150
Dim ST As New Label()
ST.ID = "ST"
ST.Text = FormatNumber(TryCast(e.Row.DataItem, DataRowView).Row("Std.Time").ToString(), 2)
e.Row.Cells(5).Controls.Add(ST)
e.Row.Cells(5).HorizontalAlign = HorizontalAlign.Right
ST.Width = 30
Dim TON As New Label()
TON.ID = "TON"
TON.Text = TryCast(e.Row.DataItem, DataRowView).Row("Tonnage").ToString()
e.Row.Cells(6).Controls.Add(TON)
e.Row.Cells(6).HorizontalAlign = HorizontalAlign.Right
TON.Width = 40
Dim MachineNo As New Label()
MachineNo.ID = "MachineNo"
MachineNo.Text = TryCast(e.Row.DataItem, DataRowView).Row("MachineNo").ToString()
e.Row.Cells(7).Controls.Add(MachineNo)
MachineNo.Width = 50
Dim TRP As New Label()
TRP.ID = "TRP"
TRP.Text = TryCast(e.Row.DataItem, DataRowView).Row("TRP").ToString()
e.Row.Cells(10).Controls.Add(TRP)
TRP.Width = 50
Dim FixedMachine As New Label()
Dim strFix As String
FixedMachine.ID = "FixedMachine"
FixedMachine.Text = TryCast(e.Row.DataItem, DataRowView).Row("FixedMachine").ToString()
e.Row.Cells(8).Controls.Add(FixedMachine)
FixedMachine.Width = 50
Dim chkSel As New CheckBox
chkSel.ID = "Move"
chkSel.Checked = False
e.Row.Cells(0).Controls.Add(chkSel)
Dim row As GridViewRow = TryCast(FixedMachine.NamingContainer, GridViewRow)
strFix = TryCast(row.FindControl("FixedMachine"), Label).Text
If String.IsNullOrEmpty(strFix) Then
chkSel.Enabled = True
Else
chkSel.Enabled = True
' chkSel.Enabled = False
End If
' AddGrdColumn("AvailableTime", "Available Time", "Lable")
'getsum
strGrpMC = TON.Text & MachineNo.Text
For i As Integer = 0 To iLoopMonth - 1
Dim ShpOrd As New Label()
Dim ShpOrdBckOrd As New TextBox()
Dim PlanM1 As New TextBox()
Dim ActualM1 As New TextBox()
Dim BackOrder As New Label()
Dim NeedHr As New Label()
ShpOrd.ID = "ShpOrd"
ShpOrd.Text = TryCast(e.Row.DataItem, DataRowView).Row(arrayMonth(i)).ToString()
e.Row.Cells(11 + (9 * i) + i).Controls.Add(ShpOrd)
ShpOrd.Width = 50
ShpOrdBckOrd.ID = "ShpOrdBckOrd"
ShpOrdBckOrd.Text = ShpOrd.Text
e.Row.Cells(12 + (9 * i) + i).Controls.Add(ShpOrdBckOrd)
ShpOrdBckOrd.Width = 50
PlanM1.ID = "PlanM1"
PlanM1.Text = ""
e.Row.Cells(13 + (9 * i) + i).Controls.Add(PlanM1)
PlanM1.Width = 50
ActualM1.ID = "ActualM1"
ActualM1.Text = ""
ActualM1.AutoPostBack = True
AddHandler ActualM1.TextChanged, AddressOf txtAcutal_TextChanged
e.Row.Cells(14 + (9 * i) + i).Controls.Add(ActualM1)
ActualM1.Width = 50
BackOrder.ID = "BackOrder"
BackOrder.Text = ""
BackOrder.Text = GetBackOrder(ShpOrdBckOrd.Text, ActualM1.Text)
e.Row.Cells(15 + (9 * i) + i).Controls.Add(BackOrder)
BackOrder.Width = 50
NeedHr.ID = "NeedHr"
NeedHr.Text = GetNeedHr(ShpOrd.Text, PlanM1.Text, ST.Text, TRP.Text)
e.Row.Cells(16 + (9 * i) + i).Controls.Add(NeedHr)
NeedHr.Width = 50
' summary
' MsgBox("strGrpMC : " & strGrpMC)
' MsgBox("strTmpGrpMC : " & strTmpGrpMC)
strGrpMC = TON.Text & "-" & MachineNo.Text
If strGrpMC <> strTmpGrpMC Then
LodTmeTT = 0
BalTmeTT = 0
strTmpGrpMC = strGrpMC
strGrpMC = TON.Text & "-" & MachineNo.Text
LodTmeTT = LodTmeTT + Convert.ToDouble(ChkNull(GetNeedHr(ShpOrd.Text, PlanM1.Text, ST.Text, TRP.Text), 0))
Else
strTmpGrpMC = strGrpMC
strGrpMC = TON.Text & "-" & MachineNo.Text
LodTmeTT = LodTmeTT + Convert.ToDouble(ChkNull(GetNeedHr(ShpOrd.Text, PlanM1.Text, ST.Text, TRP.Text), 0))
End If
'("#,##0.00")
Dim AvailableTime As New TextBox()
AvailableTime.ID = "AvailableTime"
AvailableTime.Text = TryCast(e.Row.DataItem, DataRowView).Row("AvailableTime").ToString()
e.Row.Cells(18 + (9 * i) + i).Controls.Add(AvailableTime)
AvailableTime.Width = 50
Dim Loading As New Label()
Loading.ID = "Loading"
Loading.Text = LodTmeTT
e.Row.Cells(17 + (9 * i) + i).Controls.Add(Loading)
Loading.Width = 50
Loading.Text = LodTmeTT
Dim balTme As New Label()
balTme.ID = "balTme"
balTme.Text = GetBalTime(AvailableTime.Text, Loading.Text)
e.Row.Cells(19 + (9 * i) + i).Controls.Add(balTme)
balTme.Width = 50
Dim RatioTme As New Label()
RatioTme.ID = "RatioTme"
RatioTme.Text = GetLoadRatioTime(Loading.Text, AvailableTime.Text)
e.Row.Cells(20 + (9 * i) + i).Controls.Add(RatioTme)
RatioTme.Width = 50
Next
End If
End Sub
My Public Class is Below:
public class GlobalVariable
public shared listbox2Count = listbox2.items.count
public shared containsListbox2Item
End Class
my code where i assign a text item to a variable object:
Public Function getListBoxText()
If ListBox2.Text = "X,Y Coordinate" Then
GlobalVariable.containsListBox2Item = "X,Y Coordinate"
ElseIf ListBox2.Text = "Latitude, Longitude" Then
GlobalVariable.containsListBox2Item = "Latitude, Longitude"
Return Nothing
End Function
My code where i am stuck is below:
Dim dt As New DataTable
dt.Clear()
For i As Integer = 0 To GlobalVariable.listbox2Count - 1
If GlobalVariable.containsListBox2Item(i) = "X,Y Coordinate" Then
dt.Columns.Add("X Coordinate")
dt.Columns.Add("Y Coordinate")
ElseIf GlobalVariable.containsListBox2Item(i) = "Latitude, Longitude" Then
If (Not dt.Columns.Contains("Latitude")) Then dt.Columns.Add("Latitude")
If (Not dt.Columns.Contains("Longitude")) Then dt.Columns.Add("Longitude")
End If
Next
Dim mr As DataRow
mr = dt.NewRow
mr("X Coordinate") = "203910"
mr("Y Coordinate") = "190280"
mr("Latitude") = "100022"
mr("Longitude") = "201999"
dt.Rows.Add(mr)
GridView1.DataSource = dt
GridView1.DataBind()
I am absolutely not sure whats wrong with this code and if someone can help me or correct it for me would be great help Thanks. I want to add all four columns into the grid view. and then keep adding more and more columns using else if.
Try this, its extensive but it does work, it displays all the values you have on listbox2
Dim i As Integer
Dim dt As New DataTable
Dim Card As String = ""
Dim Geo As String = ""
For i = 0 To ListBox2.Items.Count - 1
If ListBox2.Items.Item(i).Text = "X,Y Coordinate" Then
If Card = "ok" Then
Else
dt.Columns.Add("X Coordinate")
dt.Columns.Add("Y Coordinate")
Card = "ok"
End If
ElseIf ListBox2.Items.Item(i).Text = "Latitude, Longitude" Then
If Geo = "ok" Then
Else
dt.Columns.Add("Latitude")
dt.Columns.Add("Longitude")
Geo = "ok"
End If
End If
Next
Dim mr As DataRow
For i = 0 To ListBox2.Items.Count - 1
If ListBox2.Items.Item(i).Text.Contains(dt.Columns.Item(0).ToString.Substring(0, 1)) Then
If dt.Columns.Item(0).ToString = "Latitude" Then
mr = dt.NewRow
mr("Latitude") = "100909"
mr("Longitude") = "1002929"
ElseIf dt.Columns.Item(0).ToString = "X Coordinate" Then
mr = dt.NewRow
mr("X Coordinate") = "909090"
mr("Y Coordinate") = "109209"
End If
End If
If ListBox2.Items.Item(i).Text.Contains(dt.Columns.Item(2).ToString.Substring(0, 1)) Then
If dt.Columns.Item(2).ToString = "Latitude" Then
mr("Latitude") = "100909"
mr("Longitude") = "1002929"
ElseIf dt.Columns.Item(2).ToString = "X Coordinate" Then
mr("X Coordinate") = "909090"
mr("Y Coordinate") = "109209"
End If
End If
Dim res As Integer
res = i Mod 2
If res > 0 Or i = ListBox2.Items.Count - 1 Then
dt.Rows.Add(mr)
GridView1.DataSource = dt
GridView1.DataBind()
End If
Next
Simple Form that defines a GridView by using the contents of a ListBox to provide Column Information
Important I've altered the ListBox Values to represent Column Headers. See why below.
<form id="form1" runat="server">
<div>
<asp:ListBox ID="ListBox2" runat="server">
<asp:ListItem Text="X,Y Coordinate" Value="X Coordinate, Y Coordinate" />
<asp:ListItem Text="Latitude, Longitude" Value="Latitude, Longitude" />
</asp:ListBox>
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true"
EmptyDataText="No Data" ShowHeader="true">
</asp:GridView>
</div>
</form>
Code Behind
Public Class WebForm1
Inherits System.Web.UI.Page
' DataTable Name and Application Cache Key
Const DataTableCacheKey As String = "CoordinatesDataTable"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Create the Table and add to Cache, only once
If Not Page.IsPostBack Then
CreateDataTableFromListView()
End If
GridView1.DataSource = Cache(DataTableCacheKey)
GridView1.DataBind()
End Sub
Create the DataSource
NOTE: By using the Value Property of the ListItem as a comma separated list of strings, you can associate multiple columns to a given Coordinate system. Note this is not the ideal way because there is no way set up a data type, I'm assuming everything is a Double value. Still it's far better than a long string of If conditions to determine columns and headers.
' All the magic happens here...
Private Sub CreateDataTableFromListView()
' Instantiate a DataTable with a table name
Dim dt As New DataTable(DataTableCacheKey)
' Loop throught the ListBox and...
For Each li As ListItem In ListBox2.Items
' Split each Value Property into an array
' of strings to use as Column identifiers
Dim ColumnHeaders() As String = li.Value.Split(",")
' Loop through the array of strings to create
' DataTable Columns
For Each ch As String In ColumnHeaders
dt.Columns.Add(ch, GetType(Double))
Next
Next
' Add an initial Blank Row
Dim row As DataRow = dt.NewRow()
' Loop Through Columns and set a default
' value of 0 for each column
For Each c As DataColumn In dt.Columns
row(c.ColumnName) = 0
Next
' Add the Row to the Table
dt.Rows.Add(row)
' Persist the DataTable to the Application cache
Cache(DataTableCacheKey) = dt
End Sub
End Class
I have the following table row on my .aspx page:
<tr>
<td valign="bottom" style="width: 157px">Initial Requirements: </td>
<asp:Repeater ID="Repeater11" runat="server" DataSourceID="ObjectDataSource1">
<ItemTemplate>
<td valign="bottom" id="ReqStatus" runat="server" style="background-color: Gray">
<%#ReqStatus(CType(CType(Container.DataItem, System.Data.DataRowView).Row, DataSet1.DataTable1Row))%>
</td>
</ItemTemplate>
</asp:Repeater>
</tr>
In the code behind I have this function:
Protected Function ReqStatus(ByVal Project As DataSet1.DataTable1Row) As String
'Dim ReqTableCell As TableCell
'ReqTableCell = form1.FindControl("ReqStatus")
' Check the status of the Development Completed
Dim rightNow As Date = Now()
Dim dateDifference As TimeSpan
If Not Project.IsNull("Requirements_Target") Then
Dim ReqTargetDate As Date = Project.Requirements_Target
If Project.IsNull("Req_Date") Then
dateDifference = ReqTargetDate.Subtract(rightNow)
If dateDifference.Days > 0 Then
If dateDifference.Days >= 60 Then
'ReqTableCell.BackColor = Drawing.Color.Green
Return "<strong><font color='green'>" & dateDifference.Days & "</font></strong>"
ElseIf dateDifference.Days > 30 And dateDifference.Days < 60 Then
'ReqTableCell.BackColor = Drawing.Color.Yellow
Return "<strong><font color='yellow'>" & dateDifference.Days & "</font></strong>"
Else
'ReqTableCell.BackColor = Drawing.Color.Red
Return "<strong><font color='red'>" & dateDifference.Days & "</font></strong>"
End If
Else
'ReqTableCell.BackColor = Drawing.Color.Red
Dim pastDue As Int16 = (dateDifference.Days * -1)
Return "<strong><font color='red'>" & pastDue & "</font></strong> days past"
End If
End If
Else
End If
End Function
I can change the color of the return value based on conditional statements but cannot figure out the correct syntax to change the table cell back ground. My attempt is commented out.
How do I correctly declare the table cell? Findcontrol must not be the correct way.
Look this snipping of my solution:
TableRow tr = new TableRow();
TableCell tc = new TableCell { Text = "someText"};
tc.BackColor = ColorTranslator.FromHtml("#0000FF");
tc.ForeColor = ColorTranslator.FromHtml("#FFFFFF");
tc.Font.Bold = true;
tc.Font.Size = 16;
tr.Cells.Add(tc);
table.Rows.Add(tr);
After doing this and controlling all statements you can render the table in web page.
You can do that in Codebehind with full control (untested, only to give you the idea):
Private Sub Repeater1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater1.ItemDataBound
Select Case e.Item.ItemType
Case ListItemType.Item
Dim Project As DataSet1.DataTable1Row = DirectCast(DirectCast(e.Item.DataItem, System.Data.DataRowView).Row, DataSet1.DataTable1Row)
Dim tdReqStatus As HtmlTableCell = DirectCast(e.Item.FindControl("tdReqStatus"), HtmlTableCell)
Dim lblReqStatus As Label = DirectCast(e.Item.FindControl("lblReqStatus"), Label)
' Check the status of the Development Completed
Dim rightNow As Date = Now()
Dim dateDifference As TimeSpan
If Not Project.IsNull("Requirements_Target") Then
Dim ReqTargetDate As Date = Project.Requirements_Target
If Project.IsNull("Req_Date") Then
dateDifference = ReqTargetDate.Subtract(rightNow)
lblReqStatus.Font.Bold = True
If dateDifference.Days > 0 Then
If dateDifference.Days >= 60 Then
tdReqStatus.BgColor = "Green"
lblReqStatus.Text = dateDifference.Days.ToString
ElseIf dateDifference.Days > 30 And dateDifference.Days < 60 Then
tdReqStatus.BgColor = "Yellow"
lblReqStatus.Text = dateDifference.Days.ToString
Else
tdReqStatus.BgColor = "Red"
lblReqStatus.Text = dateDifference.Days.ToString
End If
Else
tdReqStatus.BgColor = "Red"
lblReqStatus.Text = (dateDifference.Days * -1).ToString
End If
End If
End If
End Select
End Sub
and on the aspx:
<table>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<tr>
<td valign="bottom" id="TdReqStatus" runat="server" >
<asp:label ID="lblReqStatus" runat="server" ></asp:label>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>