I've been battling with this issue for a couple of days now and would really appreciate if someone would shed some light for me.
I am populating a dropdownlist based on the selection from another dorpdownlist. As long as there is no postback happening, I see the list getting populated correctly but after a postback, my dropdownlist is empty.
At first, I was trying to manually set the Text property of the ddl but it kept giving me the following error:
System.ArgumentOutOfRangeException: ..ddl has a SelectedValue which is invalid because it does not exist in the list
Then I read somewhere that I need to set the DataValueField property instead so I did that which got rid of the error but now I see the empty dll after a postback.
The ViewStateMode for the ddl is set to Enabled.
The two ddls I'm referring to are defined in a Formview in my .aspx file as ddlCompanyBuyerNVListInsert and ddlCompanyNameListInsert(I'm listing the Insert mode only).
Based on the selections made in ddlCompanyBuyerNVList, I'm populating ddlCompanyNameList.
Here's the code behind for Page_Load and the functions that populate ddlCompanyNameList.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
If NavHelper.User.UserName = "" Then
Dim UserIP As String
Dim UserLogin As String
Dim UserEmail As String
UserIP = HttpContext.Current.Request.UserHostAddress
UserLogin = HttpContext.Current.Session("Username")
UserEmail = HttpContext.Current.Session("Email")
GetUserInfo()
CurrentRFQ = Nothing
If NavHelper.RFQ.ID = -1 Then
formview_RFQ.ChangeMode(FormViewMode.Insert)
tabpanelCustomerParts.Visible = False
tabpanelDocuments.Visible = False
tabpanelReviews.Visible = False
tabpanelRFQReviewHistory.Visible = False
listview_CustomerParts.Dispose()
Else
formview_RFQ.ChangeMode(FormViewMode.Edit)
listview_ReviewContracts_Initial.EditIndex = 0
SessionHelper.CurrentObject = TAA.Library.RFQ.GetObject(NavHelper.RFQ.ID)
mRFQ = DirectCast(SessionHelper.CurrentObject, TAA.Library.RFQ)
Dim UserdeptTotal As Long
UserdeptTotal = HttpContext.Current.Session("DepartmentTotal")
If formview_RFQ.FindControl("ddlCompanyBuyerNVList") IsNot Nothing Then
Dim ddl As DropDownList = DirectCast(formview_RFQ.FindControl("ddlCompanyBuyerNVList"), DropDownList)
FillCompanyNameDropDownList(ddl)
End If
tabpanelCustomerParts.Visible = True
tabpanelDocuments.Visible = True
tabpanelReviews.Visible = True
tabpanelRFQReviewHistory.Visible = True
If NavHelper.RFQ.Copy = True Then
SetModifyCopy()
End If
End If
Else 'IsPostBack
datasource_BuyerNVList.Dispose()
datasource_RFQ.DataBind()
datasource_RFQNote.DataBind()
Dim ddl As DropDownList
If (formview_RFQ.CurrentMode = FormViewMode.Insert) Then
ddl = DirectCast(formview_RFQ.FindControl("ddlCompanyBuyerNVListInsert"), DropDownList)
ElseIf formview_RFQ.FindControl("ddlCompanyBuyerNVList") IsNot Nothing Then
ddl = DirectCast(formview_RFQ.FindControl("ddlCompanyBuyerNVList"), DropDownList)
End If
FillCompanyNameDropDownList(ddl)
End If
End If
End Sub
Protected Sub FillCompanyNameDropDownList(ddlCompanyBuyerNamesList As DropDownList)
Try
Using cn As New SqlClient.SqlConnection(DB.RFQconnection)
cn.Open()
Using cm As SqlClient.SqlCommand = cn.CreateCommand
cm.CommandType = CommandType.StoredProcedure
cm.CommandText = "GetCompanyNamesForThisBuyer"
cm.Parameters.AddWithValue("#BuyerName", (ddlCompanyBuyerNamesList.SelectedItem.Text))
Dim ddlCompanyNamesList As DropDownList
If (formview_RFQ.CurrentMode = FormViewMode.Insert) Then
ddlCompanyNamesList = DirectCast(formview_RFQ.FindControl("ddlCompanyNameListInsert"), DropDownList)
Else
ddlCompanyNamesList = DirectCast(formview_RFQ.FindControl("ddlCompanyNameList"), DropDownList)
End If
Using r As New SCF.Data.SafeDataReader(cm.ExecuteReader)
ddlCompanyNamesList.Items.Clear()
ddlCompanyNamesList.Items.Add(New ListItem("Select Company"))
While r.Read
Dim li As ListItem = New ListItem()
li.Value = SCF.Data.SafeData.SafeInteger(r("CompanyBuyerId"))
li.Text = SCF.Data.SafeData.SafeString(r("CompanyName"))
ddlCompanyNamesList.Items.Add(li)
End While
End Using
cm.Dispose()
cn.Close()
' if more than one entry found, clear the company info fields until a selection is made
If ddlCompanyNamesList.Items.Count > 2 Then 'because we've added a "Select Company" as the first item
ClearCompanyInfoFields() ' company fields are text boxes that get cleared here
ddlCompanyNamesList.SelectedIndex = 0
End If
ddlCompanyNamesList.Enabled = True
If ddlCompanyNamesList.Items.Count = 2 Then ' if only one entry found populate the compny info with that one entry's selection
ddlCompanyNamesList.SelectedIndex = 1
FillCompanyInfoFields(ddlCompanyNamesList)
ElseIf ddlCompanyNamesList.Items.Count = 0 Then ' if nothing found use the buyer list to populate company info fields
ddlCompanyNamesList.Items.Clear()
FillCompanyInfoFields(ddlCompanyBuyerNamesList)
ddlCompanyNamesList.Enabled = False
End If
End Using
End Using
Catch ex As System.Exception
SetErrorPanel("An error occured during FillCompanyNameDropDownList.")
Dim err As New HealthMonitoringCustomEvents.ErrorEvent("An error occured during FillCompanyNameDropDownList", Me, ex)
err.Raise()
End Try
End Sub
Protected Sub FillCompanyInfoFields(ddl As DropDownList)
Try
Dim buyerTitle As TextBox
Dim buyerEmail As TextBox
Dim buyerPhone As TextBox
Dim buyerExt As TextBox
Dim buyerMobile As TextBox
Dim buyerFax As TextBox
Dim CoAddr As TextBox
Dim CoCity As TextBox
Dim CoState As TextBox
Dim CoZip As TextBox
If (formview_RFQ.CurrentMode = FormViewMode.Insert) Then
buyerTitle = DirectCast(formview_RFQ.FindControl("txtBuyerTitleInsert"), TextBox)
buyerEmail = DirectCast(formview_RFQ.FindControl("txtBuyerEmailInsert"), TextBox)
buyerPhone = DirectCast(formview_RFQ.FindControl("txtBuyerPhoneNumberInsert"), TextBox)
buyerExt = DirectCast(formview_RFQ.FindControl("txtExtInsert"), TextBox)
buyerMobile = DirectCast(formview_RFQ.FindControl("txtBuyerMobileNumberInsert"), TextBox)
buyerFax = DirectCast(formview_RFQ.FindControl("txtBuyerFaxNumberInsert"), TextBox)
CoAddr = DirectCast(formview_RFQ.FindControl("txtCompanyAddressInsert"), TextBox)
CoCity = DirectCast(formview_RFQ.FindControl("txtCompanyCityInsert"), TextBox)
CoState = DirectCast(formview_RFQ.FindControl("txtCompanyStateCodeInsert"), TextBox)
CoZip = DirectCast(formview_RFQ.FindControl("txtCompanyZipCodeInsert"), TextBox)
Else
buyerTitle = DirectCast(formview_RFQ.FindControl("txtBuyerTitle"), TextBox)
buyerEmail = DirectCast(formview_RFQ.FindControl("txtBuyerEmail"), TextBox)
buyerPhone = DirectCast(formview_RFQ.FindControl("txtBuyerPhoneNumber"), TextBox)
buyerExt = DirectCast(formview_RFQ.FindControl("txtExt"), TextBox)
buyerMobile = DirectCast(formview_RFQ.FindControl("txtBuyerMobileNumber"), TextBox)
buyerFax = DirectCast(formview_RFQ.FindControl("txtBuyerFaxNumber"), TextBox)
CoAddr = DirectCast(formview_RFQ.FindControl("txtCompanyAddress"), TextBox)
CoCity = DirectCast(formview_RFQ.FindControl("txtCompanyCity"), TextBox)
CoState = DirectCast(formview_RFQ.FindControl("txtCompanyStateCode"), TextBox)
CoZip = DirectCast(formview_RFQ.FindControl("txtCompanyZipCode"), TextBox)
End If
Using cn As New SqlClient.SqlConnection(DB.RFQconnection)
cn.Open()
Using cm As SqlClient.SqlCommand = cn.CreateCommand
cm.CommandType = CommandType.StoredProcedure
cm.CommandText = "GetBuyerCompanyInfo"
cm.Parameters.AddWithValue("#companyBuyerId", (ddl.SelectedValue))
Using r As New SCF.Data.SafeDataReader(cm.ExecuteReader)
' populate company information fields in CurrentRFQ
While r.Read
CurrentRFQ.CompanyID = SCF.Data.SafeData.SafeString(r(0))
CurrentRFQ.CompanyBuyerId = SCF.Data.SafeData.SafeString(r(7))
ddl.DataValueField = SCF.Data.SafeData.SafeString(r(1))
CoAddr.Text = SCF.Data.SafeData.SafeString(r(2))
CoCity.Text = SCF.Data.SafeData.SafeString(r(4))
CoState.Text = SCF.Data.SafeData.SafeString(r(5))
CoZip.Text = SCF.Data.SafeData.SafeString(r(6))
buyerTitle.Text = SCF.Data.SafeData.SafeString(r(9))
buyerEmail.Text = SCF.Data.SafeData.SafeString(r(10))
buyerPhone.Text = SCF.Data.SafeData.SafeString(r(11))
buyerExt.Text = SCF.Data.SafeData.SafeString(r(12))
buyerMobile.Text = SCF.Data.SafeData.SafeString(r(13))
buyerFax.Text = SCF.Data.SafeData.SafeString(r(14))
End While
End Using
cm.Dispose()
cn.Close()
End Using
End Using
Catch ex As System.Exception
SetErrorPanel("An error occured during FillCompanyInfoFields.")
Dim err As New HealthMonitoringCustomEvents.ErrorEvent("An error occured during FillCompanyInfoFields", Me, ex)
err.Raise()
End Try
End Sub
And here's how the two ddls are defined in the .aspx file.
<td> <asp:DropDownList ID="ddlCompanyBuyerNVListInsert" runat="server"
AppendDataBoundItems="true" AutoPostBack="true" CssClass="Input"
DataSourceID="datasource_BuyerNVlist" DataTextField="Key" DataValueField="Value"
OnSelectedIndexChanged="ddlCompanyBuyerNVListInsert_SelectedIndexChanged"
ViewStateMode="Enabled" Width="205px"> <asp:ListItem Selected="True" Text="Select
Buyer" Value="0" /> </asp:DropDownList> </td> <td></td> <td class="style4"> Company:
</td> <td>
<asp:DropDownList ID="ddlCompanyNameListInsert" runat="server"
AppendDataBoundItems="True" AutoPostBack="True" CssClass="Input"onselectedindexchanged="ddlCompanyNameListInsert_SelectedIndexChanged"
ViewStateMode="Enabled" Enabled="False"> </asp:DropDownList> </td>
Thank you so much for your response.
Related
I am trying to use checkbox for multiple select in GridView to delete records.
Here is my Code :-
Protected Sub btnDelete_Click(sender As Object, e As EventArgs)
Try
'Loop through all the rows in gridview
For Each grv As GridViewRow In GridView1.Rows
'Finiding checkbox control in gridview for particular row
Dim chk As CheckBox = CType(grv.FindControl("chkSelect"), CheckBox)
If chk.Checked Then
'get EmpId from DatakeyNames from gridview
Dim empid As Integer = Convert.ToInt32(GridView1.DataKeys(grv.RowIndex).Value)
cmd = New SqlCommand("DeleteRecord_Sp", con)
cmd.Parameters.Add("#Id", SqlDbType.Int).Value = empid
cmd.CommandType = CommandType.StoredProcedure
cmd.ExecuteNonQuery()
End If
Next
GridView1.EditIndex = -1
DisplayData()
ScriptManager.RegisterClientScriptBlock(Page, Page.[GetType](), Guid.NewGuid().ToString(), "alert('Selected Records has been deleted successfully');", True)
Catch ex As Exception
ScriptManager.RegisterStartupScript(Me, Me.[GetType](), "Message", "alert('Error occured : " & ex.Message.ToString() & "');", True)
Finally
cmd.Dispose()
con.Close()
End Try
End Sub
Inside Grid View :-
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
<asp:Button ID="btnDelete" runat="server" Text="Multiple Delete"
OnClientClick="return confirm('Are you sure you want to delete selected records?')"
OnClick="btnDelete_Click" />
I am getting error in this line :-
Dim chk As CheckBox = CType(grv.FindControl("chkSelect"), CheckBox)
Value of type 'Control' cannot be converted to 'CheckBox' in vb.net
This is because Ctype returns a collection, and not a single item
you need DirectCast to cast a single item. But since you are catching it into a variable, you do not need to at all.
Dim chk As CheckBox = grv.FindControl("chkSelect")
But you might also simply Acces it by its name. without 'finding' it, and without catching it into a variable.
If ChkSelect.Checked then
end if
Please bear with me a bit as I try to explain my problem.
I have multiple GridView controls, each with its own checkbox and textboxes.
User must either check the checkboxes or enter data into all textboxes.
If checkbox is not checked and textboxes within a particular gridview control is empty, when a user clicks the NEXT button of a multiview control, an error is raised.
The following code shows two FOR loops inside button click event of the NEXT navigation button.
The first Gridview1 FOR loop works great. If checkbox is not checked and the textboxes are empty, an alert message is displayed and user cannot navigate to next page.
If however, either the checkbox is checked or textboxes are filled with data, user can then successfully navigate to the next page.
The issue is with the second FOR loop for grvspouse gridview control.
If checkbox is not checked and textboxes are empty, the alert box is displayed with message that user must checkbox or enter data into textboxes. This is fine. However, the problem is that user is still taken to the next page.
Is there a way to handle multiple FOR loops inside BTN_NEXT navigation event handler?
Protected Sub btnNext_Click(ByVal sender As Object, ByVal e As EventArgs)
'If the message failed at some point, let the user know
For Each row As GridViewRow In Gridview1.Rows
Dim namesource As TextBox = TryCast(row.FindControl("txtsourcename"), TextBox)
Dim nmesource As String = namesource.Text
Dim addresssource As TextBox = TryCast(row.FindControl("txtsourceaddress"), TextBox)
Dim addrsource As String = addresssource.Text
Dim incomesource As TextBox = TryCast(row.FindControl("txtsourceincome"), TextBox)
Dim incmsource As String = incomesource.Text
Dim ckb As CheckBox = TryCast(row.FindControl("grid1Details"), CheckBox)
Dim checkb As Boolean = ckb.Checked
If checkb = False AndAlso nmesource = "" AndAlso addrsource = "" AndAlso incmsource = "" Then
ClientScript.RegisterStartupScript([GetType](), "Confirm", "jAlert('Please enter values on all textboxes or check the checkbox next to each textbox!');", True)
Else
myMultiView.ActiveViewIndex += 1
lblResult.Visible = True
End If
Next
For Each row As GridViewRow In grvspouse.Rows
Dim namespouse As TextBox = TryCast(row.FindControl("txtspousename"), TextBox)
Dim nmespouse As String = namespouse.Text
Dim addressspouse As TextBox = TryCast(row.FindControl("txtspouseaddress"), TextBox)
Dim addrspouse As String = addressspouse.Text
Dim incomespouse As TextBox = TryCast(row.FindControl("txtspouseincome"), TextBox)
Dim incmspouse As String = incomespouse.Text
Dim ckb2 As CheckBox = TryCast(row.FindControl("spouseDetails"), CheckBox)
Dim checkc As Boolean = ckb2.Checked
If checkc = False AndAlso nmespouse = "" AndAlso addrspouse = "" AndAlso incmspouse = "" Then
ClientScript.RegisterStartupScript([GetType](), "Confirm", "jAlert('Please enter values on all textboxes or check the checkbox next to each textbox!');", True)
Else
myMultiView.ActiveViewIndex += 1
lblResult.Visible = True
End If
Next
End Sub
[Edited]
You are facing this problem because you coded it that way....The easiest fix would be to create a STRING VARIABLE object and by each click,the program would check the VARIABLEfor a desired value and if the value matches then it'ld move to the next form.A complete example would look like this :
'Create a VARIABLE named HITCOUNT and keep the value empty at first.
Public class MyProject
Dim HITCOUNT as string = ""
If HITCOUNT = "" Then
For Each row As GridViewRow In Gridview1.Rows
Dim namesource As TextBox = TryCast(row.FindControl("txtsourcename"), TextBox)
Dim nmesource As String = namesource.Text
Dim addresssource As TextBox = TryCast(row.FindControl("txtsourceaddress"), TextBox)
Dim addrsource As String = addresssource.Text
Dim incomesource As TextBox = TryCast(row.FindControl("txtsourceincome"), TextBox)
Dim incmsource As String = incomesource.Text
Dim ckb As CheckBox = TryCast(row.FindControl("grid1Details"), CheckBox)
Dim checkb As Boolean = ckb.Checked
If checkb = False AndAlso nmesource = "" AndAlso addrsource = "" AndAlso incmsource = "" Then
ClientScript.RegisterStartupScript([GetType](), "Confirm", "jAlert('Please enter values on all textboxes or check the checkbox next to each textbox!');", True)
Else
myMultiView.ActiveViewIndex += 1
lblResult.Visible = True
End If
Next
HITCOUNT = "1" 'adding an integer value of 1(you can add anything)
End if
If HITCOUNT = "1" then
For Each row As GridViewRow In grvspouse.Rows
Dim namespouse As TextBox = TryCast(row.FindControl("txtspousename"), TextBox)
Dim nmespouse As String = namespouse.Text
Dim addressspouse As TextBox = TryCast(row.FindControl("txtspouseaddress"), TextBox)
Dim addrspouse As String = addressspouse.Text
Dim incomespouse As TextBox = TryCast(row.FindControl("txtspouseincome"), TextBox)
Dim incmspouse As String = incomespouse.Text
Dim ckb2 As CheckBox = TryCast(row.FindControl("spouseDetails"), CheckBox)
Dim checkc As Boolean = ckb2.Checked
If checkc = False AndAlso nmespouse = "" AndAlso addrspouse = "" AndAlso incmspouse = "" Then
ClientScript.RegisterStartupScript([GetType](), "Confirm", "jAlert('Please enter values on all textboxes or check the checkbox next to each textbox!');", True)
Else
myMultiView.ActiveViewIndex += 1
lblResult.Visible = True
End If
Next
HITCOUNT="2"
End if
'and move on and on
This is just one way and maybe the quickest one.There are many other ways to do so.If you don't wanna use this one, just comment and i'll post another solution
I need help to restrict my textbox to accept just numbers. I have another textbox event textchanged and in that condition I want to not allow user to write other characters than numbers. have implemented the maxlength but I can't validate to accpet just numbers.
here is my condition that I want to implement in:
Protected Sub txtIdType_TextChanged(sender As Object, e As EventArgs)
Dim txtb As TextBox = CType(FormViewPerson.FindControl("txtIdType"), TextBox)
Dim txtb1 As TextBox = CType(FormViewPerson.FindControl("TextBoxIDCode"), TextBox)
If (txtb.Text = "Leternjoftimi" OrElse txtb.Text = "KosovoIDCard" OrElse txtb.Text = "Licna karta") Then
txtb1.MaxLength = 10
End If
End Sub
You can do this simply in aspx page, like below:-
<asp:TextBox ID="txtNumbers" runat="server" autocomplete="off" ValidationGroup="AddNew"></asp:TextBox>
<asp:RegularExpressionValidator ID="regNumbers" runat="server" ErrorMessage="Only numbers are allowed" ControlToValidate="txtNumbers" ValidationExpression="^[0-9]*$" ValidationGroup="AddNew"></asp:RegularExpressionValidator>
You don't need to use the code-behind for this.
Hope this helps
You can add the validator from code behind. Try to do the following:
Protected Sub txtIdType_TextChanged(sender As Object, e As EventArgs)
Dim txtb As TextBox = CType(FormViewPerson.FindControl("txtIdType"), TextBox)
Dim txtb1 As TextBox = CType(FormViewPerson.FindControl("TextBoxIDCode"), TextBox)
If (txtb.Text = "Leternjoftimi" OrElse txtb.Text = "KosovoIDCard" OrElse txtb.Text = "Licna karta") Then
txtb1.MaxLength = 10
Dim validator As New RegularExpressionValidator()
validator.ID = "validator" + New Random().[Next](100, 1000)
validator.ControlToValidate = CType(FormViewPerson.FindControl("TextBoxIDCode"), TextBox).ID
validator.ValidationExpression="^[0-9]*$"
FormViewPerson.Controls.Add(validator)
End If
End Sub
Suksese!
I solved my problem using this function :
For Each ch As Char In txt.Text
If Not Char.IsDigit(ch) Then
txt.Text = ""
Exit Sub
End If
Next
This one is REALLY driving me nuts. I've read, and tried, most of the workarounds but still it posts back!!
All the markup is generated dynamically from code-behind and inserted into a page that is part of a Master Page, from the init event.
There are a series of nested tabs, the tab content for the most part is data in a GridView. Each Gridview is set in it's own update panel. Every time a LinkButton in the GridView is clicked there is a full postback causing the tabs to reset (any button outside of the GridView and in the UpdatePanel doesn't cause a full postback.
LinkButtons are generated like this
Dim Select_Field As New CommandField
With Select_Field
.HeaderText = "View Transactions"
.SelectText = "View Transactions"
.ShowSelectButton = True
End With
GV.Columns.Add(Select_Field)
Registering with ToolKitScriptManager
Private Sub AssessmentsMain_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Try
If e.Row.RowType = DataControlRowType.DataRow Then
Dim vID As Integer = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ID"))
Dim LB As LinkButton = CType(e.Row.Cells(4).Controls(0), LinkButton)
LB.ID = "AssMain_" & vID
AjaxControlToolkit.ToolkitScriptManager.GetCurrent(Me).RegisterAsyncPostBackControl(LB)
End If
Catch ex As Exception
Dim vError As New SendError
vError.MailError("840", PageName, ex)
ShowError()
End Try
End Sub
and the generated markup for one row is like this
<tr class="GridView" style="color:#333333;background-color:#F7F6F3;">
<td>10</td>
<td>Adam White</td>
<td>4224 Res Road</td>
<td align="right">$6,850.65</td>
<td>
<a id="ctl00_ContentPlaceHolder1_AssessmentsMainGV_ctl02_AssMain_10" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$AssessmentsMainGV','Select$0')" style="color:#333333;">View Transactions</a>
The GridView class
Public Class HAS_Gridview
Inherits GridView
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
CellPadding = 4
GridLines = WebControls.GridLines.None
ForeColor = Drawing.ColorTranslator.FromHtml("#333333")
ClientIDMode = UI.ClientIDMode.AutoID
With MyBase.FooterStyle
.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
.Font.Bold = True
.ForeColor = Color.White
End With
RowStyle.BackColor = Drawing.ColorTranslator.FromHtml("#F7F6F3")
RowStyle.ForeColor = Drawing.ColorTranslator.FromHtml("#333333")
PagerStyle.HorizontalAlign = WebControls.HorizontalAlign.Center
PagerStyle.ForeColor = Color.Black
PagerStyle.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
With MyBase.SelectedRowStyle
.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
.Font.Bold = True
.ForeColor = Drawing.ColorTranslator.FromHtml("#333333")
End With
With MyBase.HeaderStyle
.BackColor = Drawing.ColorTranslator.FromHtml("#E2DED6")
.Font.Bold = True
.ForeColor = Color.Black
.CssClass = "GridView"
End With
EditRowStyle.BackColor = Drawing.ColorTranslator.FromHtml("#999999")
With MyBase.AlternatingRowStyle
.BackColor = Color.White
.ForeColor = Drawing.ColorTranslator.FromHtml("#284775")
.CssClass = "GridView"
End With
With MyBase.RowStyle
.CssClass = "GridView"
End With
End Sub
End Class
Have you tried adding trigger programmatically instead of registering in AjaxControlToolkit:
Dim trigger As New AsyncPostBackTrigger()
trigger.ControlID = LB.ID
trigger.EventName = "Click"
MyUpdatePanel.Triggers.Add(trigger)
It looks like the postback is caused by href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$AssessmentsMainGV','Select$0')" in the generated markup for the anchor tag.
Try to define your own _doPostBack.
If you haven't checked post a and post b already, they offer a couple of ways to do that.
In the end the only way I could get this to work was
Create a class for a LinkButton Template
Public Class LinkButtonTemplate
Implements ITemplate
Private m_ColumnName As String
Event LinkButtonItem_Clicked(sender As LinkButton, e As EventArgs)
Public Property ColumnName() As String
Get
Return m_ColumnName
End Get
Set(ByVal value As String)
m_ColumnName = value
End Set
End Property
Public Sub New()
End Sub
Public Sub New(ByVal ColumnName As String)
Me.ColumnName = ColumnName
End Sub
Public Sub InstantiateIn(container As Control) Implements ITemplate.InstantiateIn
Dim LB As New LinkButton()
With LB
.ID = "LB_" & ColumnName
.Text = ColumnName
.OnClientClick = "LinkButtonClick(this);"
End With
container.Controls.Add(LB)
End Sub
End Class
Add this javascript so that it would post the ID to a hidden field and click a hidden button
Private Sub LoadLinkButtonClick()
Try
Dim SB As New StringBuilder
SB.Append("function LinkButtonClick(LinkButton){ ")
SB.Append("setTimeout(function() { ")
SB.Append("$get('" & GridViewLBClicked.ClientID & "').click(); ")
SB.Append(" }, 300); ")
SB.Append("var sendingID = LinkButton.id; ")
SB.Append("document.getElementById('" & HiddenField1.ClientID & "').value = sendingID; ")
SB.Append("} ")
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "LoadLinkButton", SB.ToString, True)
Catch ex As Exception
Dim vError As New SendError
vError.MailError("1229", PageName, ex)
End Try
End Sub
On the RowDataBound event capture the ID we need and add it to the LinkButton ID (so now we know both the sending GridView and the selected row)
Private Sub AssessmentsMain_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Try
If e.Row.RowType = DataControlRowType.DataRow Then
Dim vID As Integer = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ID"))
Dim LB As LinkButton = CType(e.Row.Cells(4).Controls(0), LinkButton)
LB.ID = "AssMain_" & vID
End If
Catch ex As Exception
Dim vError As New SendError
vError.MailError("840", PageName, ex)
ShowError()
End Try
End Sub
From the hidden button click we can recover all the data we need to make the async postback
Private Sub RaiseLinkButton_Click(sender As Object, e As EventArgs)
Try
Dim vFunction As New Functions
Dim vValue As String = HiddenField1.Value
Dim vSplit = vValue.Split("_")
Dim i As Integer = 0
For Count As Integer = 0 To vSplit.Length - 1
i += 1
Next
Dim DGName As String = vSplit(i - 2)
Select Case DGName
Case "AssMain"
Dim MV As MultiView = vFunction.FindControlRecursive(BodyMain, "AssessmentMultiView")
Dim GV As CustomControl.HAS_Gridview = vFunction.FindControlRecursive(BodyMain, "AssessmentDetailGV")
With GV
.DataSource = AssessmentsDetail_ReturnDataSet()
.DataBind()
.PageIndex = 0
End With
MV.ActiveViewIndex = 1
Dim vPanel As UpdatePanel = vFunction.FindControlRecursive(BodyMain, "AssessmentUpdatePanel")
vPanel.Update()
End Select
Catch ex As Exception
Dim vError As New SendError
vError.MailError("953", PageName, ex)
ShowError()
End Try
End Sub
I am creating a gridview programmatically and I want to use the solution to this question: Programmatically access GridView columns and manipulate. In other words, I want to hide the hyperlinkfield and instead display a templatefield if the value of the "submitted" column in the row is 1. I'm listing employment applications and letting the user click "Load Application" if they have not yet submitted an application, or displaying "submitted" in plain text if they have already submitted it. I know how to do this if I create my gridview in the aspx file, but I don't know how to do this when I'm creating my gridview at runtime. Here's my code:
Public Sub getSavedApps(ByVal userID As Integer)
Dim ds As New DataSet
ds = clsData.sqlGetAllApps(userID)
If ds.Tables(0).Rows.Count > 0 Then
popAppSelect.Show()
'let user select which app they want to work on
Dim grdAppSelect As New GridView
'need to find out if this row has a value of 1 or 0 for submitted
Dim submitted As Boolean
'position column
Dim fieldPosition As New BoundField
fieldPosition.DataField = "positionDesired"
fieldPosition.HeaderText = "Position Desired"
If fieldPosition.DataField.ToString = "" Then
fieldPosition.DataFormatString = "<em>No position specified</em>"
End If
Dim colPosition As DataControlField = fieldPosition
'date column
Dim fieldDate As New BoundField
fieldDate.DataField = "dateStarted"
fieldDate.HeaderText = "Date Started"
Dim colDate As DataControlField = fieldDate
Dim strAppID(0) As String
strAppID(0) = "appID"
Dim colLoad As DataControlField
'submitted column
If submitted Then
Dim fieldLoad As New TemplateField
fieldLoad.ItemTemplate = New GridViewTemplate(DataControlRowType.DataRow, "submitted")
colLoad = fieldLoad
Else
Dim fieldLoad As New HyperLinkField
fieldLoad.Text = "<b>Load Application »</b>"
fieldLoad.DataTextFormatString = "{0}"
fieldLoad.DataNavigateUrlFields = strAppID
fieldLoad.DataNavigateUrlFormatString = "?load={0}"
colLoad = fieldLoad
End If
'add the columns to the gridview
With grdAppSelect
.ID = "grdAppSelect"
.CssClass = "grdAppSelect"
.CellPadding = 5
.BorderWidth = "0"
.HeaderStyle.HorizontalAlign = HorizontalAlign.Left
With .Columns
.Add(colPosition)
.Add(colDate)
.Add(colLoad)
End With
.AutoGenerateColumns = False
.DataSource = ds.Tables(0)
.DataBind()
End With
Dim lnkNew As New HyperLink
lnkNew.Text = "<b>Start New Application »</b>"
lnkNew.NavigateUrl = "?load="
Dim strClear As New LiteralControl
strClear.Text = "<br class='clearer' />"
'add the controls to the panel
pnlAppSelect.Controls.Add(grdAppSelect)
pnlAppSelect.Controls.Add(strClear)
'pnlAppSelect.Controls.Add(lnkNew)
Else
'should be apps there but couldn't find them
lblGeneralError.Text = "Could not find any previously started applications."
End If
End Sub
I found the solution. I needed to add an event handler when I created the gridview so that I could access the RowDataBound event and do the evaluation there. Here's the event handler code I used:
AddHandler grdAppSelect.RowDataBound, AddressOf grdAppSelect_RowDataBound
Then I just did my evaluation during RowDataBound like so:
Sub grdAppSelect_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim load As Control = e.Row.Controls(2)
Dim submitted As Control = e.Row.Controls(3)
Dim submittedText As String = e.Row.Cells(3).Text
If submittedText = "True" Then
load.Visible = False
End If
submitted.Visible = False
End If
End Sub