SelectedIndexChange event won't get fired,ASP.NET DropDownList - asp.net

I have a Windows form with 1 DataGrid which has a Dropdownlist in one of its columns.
I also have another dropDownlist outside of this DataGrid.
Both of these dropdowns are bound to same dataset and both get populated with same items.
Both of DropDowns have their Autopostbacks set to true.
Problem is only for the dropdownlist Outside of Datagrid SelectedIndexChange Event gets fired:
(I have seen multiple similar questions on SO but none of suggestions works for me. So I really appreciate if you can help me here.
)
Protected Sub ABCD(ByVal sender As System.Object, ByVal e As System.EventArgs)
End Sub
For both Dropdownlists: AutoPostBack="True"
Here is Vb code:
Imports System.Data.OleDb
Public Class WebForm1
Inherits System.Web.UI.Page
Protected WithEvents dg As New System.Web.UI.WebControls.DataGrid
Private cnDB As New OleDbConnection
Private ds As New DataSet
Private daDB As New OleDbDataAdapter
Protected allNames As New DataSet
Protected MyDataSet As DataSet
Protected WithEvents DropDownList1 As System.Web.UI.WebControls.DropDownList
Protected WithEvents DropDownList2 As System.Web.UI.WebControls.DropDownList
Protected WithEvents ddlName As New System.Web.UI.WebControls.DropDownList
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
MyDataSet = NameBudget()
GridDataLoad()
End Sub
Protected Sub Grid_EditCommand(ByVal source As Object, ByVal e As DataGridCommandEventArgs)
dg.EditItemIndex = e.Item.ItemIndex
dg.DataSource = ds
dg.DataBind()
End Sub
Protected Sub Grid_CancelCommand(ByVal source As Object, ByVal e As DataGridCommandEventArgs)
dg.DataSource = ds.Tables(0).DefaultView
dg.EditItemIndex = -1
dg.DataSource = ds
dg.DataBind()
End Sub
Protected Sub Grid_UpdateCommand(ByVal source As Object, ByVal e As DataGridCommandEventArgs)
End Sub
Private Function GridDataLoad()
ddlName.DataSource = MyDataSet
Dim i As Object = MyDataSet.Tables(0)
ddlName.DataBind()
DropDownList1.DataSource = MyDataSet
DropDownList1.DataBind()
Dim strCon As String = _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\AccessTestDataBases\TestDB.mdb; "
Dim cnDB As New OleDbConnection(strCon)
cnDB.Open()
daDB = New OleDbDataAdapter("Select * from [Persons]", cnDB)
daDB.Fill(ds, "tbl1")
Dim j As Object = ds.Tables(0)
dg.DataSource = ds
dg.DataBind()
cnDB.Close()
Dim ii As Object = ds.Tables(0)
End Function
Protected Function NameEditable(ByVal n As String) As Boolean
Return True
End Function
Protected Function NameBudget() As DataSet
Dim strCon As String = _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\AccessTestDataBases\TestDB.mdb; "
Dim cnDB As New OleDbConnection(strCon)
cnDB.Open()
daDB = New OleDbDataAdapter("Select ID,Name from [Persons]", cnDB)
Dim ds As New DataSet
daDB.Fill(ds, "tbl1")
cnDB.Close()
Return ds
End Function
Sub SetDefaultListItem(ByVal sender As Object, ByVal e As System.EventArgs)
'*************************************************************************
'* Use this sub to set the Default List for DropDown Listboxes *
'*************************************************************************
Try
If Len(sender.DefaultValue) > 0 Then
If sender.Items.FindByValue(sender.DefaultValue).ToString.Length > 0 Then
sender.Items.FindByValue(sender.DefaultValue).Selected = True
End If
End If
Catch ex As System.Exception
'Throw New System.Exception(ex.ToString())
End Try
End Sub
Protected Sub ABCD(ByVal sender As System.Object, ByVal e As System.EventArgs)
End Sub
End Class
Here is the HTML for datagrid and Dropdownlists:
<Columns>
<ASP:ButtonColumn Text="Delete" CommandName="Delete"></ASP:ButtonColumn>
<asp:EditCommandColumn ButtonType="LinkButton" UpdateText="Update" CancelText="Cancel"
EditText="Edit"></asp:EditCommandColumn>
<ASP:TemplateColumn HeaderText="Name" SortExpression="FY" HeaderStyle-HorizontalAlign="center" HeaderStyle-Wrap="True">
<ItemStyle Wrap="false" HorizontalAlign="left" />
<ItemTemplate>
<ASP:Label ID="Name" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' runat="server"/>
</ItemTemplate>
<EditItemTemplate>
<ASP:DropDownList id="DropDownlist2" datasource="<%# MyDataSet %>" DataTextField= "Name" DataValueField="ID" runat="server" AutoPostBack="True" OnSelectedIndexChanged="ABCD">
</ASP:DropDownList>
</EditItemTemplate>
</ASP:TemplateColumn>
</Columns>
<asp:DropDownList id="DropDownList1"
datasource="<%# MyDataSet %>" DataTextField= "Name"
DataValueField="ID" runat="server" AutoPostBack="True"
OnSelectedIndexChanged="ABCD">
</asp:DropDownList>

Related

ItemCommand on nested Repeater

I have a simple aspx page which contains 2 nested repeaters. Each of these have buttons on them. When the user clicks on a button on the outer repeater, I can capture the ItemCommand in my codebehind, however when the user clicks on an inner one, I cannot capture it.
I have read in other threads about needing to attach the event manually to the inner repeater, but cannot work this out.
Can anyone help?
Here is the aspx. I'm using vb.net code behind
<asp:Repeater runat="server" ID="ParentRepeater">
<ItemTemplate>
<li id="P<%#DataBinder.Eval(Container, "DataItem.id")%>">
<%#DataBinder.Eval(Container, "DataItem.name")%>
<asp:Button runat="server" ID="adedit" Text="Edit" CommandName='<%#DataBinder.Eval(Container, "DataItem.id")%>'
class="pages-edit" />
<asp:Button runat="server" ID="addel" Text="Delete" CommandName='<%#DataBinder.Eval(Container, "DataItem.xid")%>'
class="pages-delete" />
<ul class="page-section sub innerdrag">
<asp:Repeater runat="server" ID="childrepeater">
<ItemTemplate>
<li id="<%#DataBinder.Eval(Container, "DataItem.id")%>,">
<%#DataBinder.Eval(Container, "DataItem.name")%><asp:Button runat="server" ID="ad_edit"
Text="Edit" CommandName='<%#DataBinder.Eval(Container, "DataItem.id")%>' class="pages-edit" />
<asp:Button runat="server" ID="ad_del" Text="Delete" CommandName='<%#DataBinder.Eval(Container, "DataItem.xid")%>'
class="pages-delete" />
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</li>
</ItemTemplate>
</asp:Repeater>
Still not firing so I've put the updated VB here too
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Dim DBFunctions As New DBFunctions.Functions
Dim dstmp As New DataSet
Dim dstmp2 As New DataSet
dstmp = DBFunctions.SQLDataSet("SELECT id,name, 'x'+cast(id as varchar(50)) as xid from pages where parent = 0 and coalesce(active,1)=1 order by orderby asc", "data")
dstmp2 = DBFunctions.SQLDataSet("SELECT id,name , 'x'+cast(id as varchar(50)) as xid,parent from pages where parent >0 and coalesce(active,1)=1 order by orderby asc", "data2")
Dim allData As New DataSet
allData.Tables.Add(dstmp.Tables(0).Copy)
allData.Tables.Add(dstmp2.Tables(0).Copy)
allData.Relations.Add(New DataRelation("Children", allData.Tables(0).Columns("ID"), allData.Tables(1).Columns("parent")))
ParentRepeater.DataSource = allData
ParentRepeater.DataBind()
sdhfunctions.Close()
End If
End Sub
Protected Sub repMenu1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles ParentRepeater.ItemDataBound
Dim dv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
If dv IsNot Nothing Then
Dim repSubMenu As Repeater = TryCast(e.Item.FindControl("childrepeater"), Repeater)
If repSubMenu IsNot Nothing Then
AddHandler repSubMenu.ItemCommand, AddressOf childrepeater_ItemCommand
repSubMenu.DataSource = dv.CreateChildView("Children")
repSubMenu.DataBind()
End If
End If
End Sub
Protected Sub ParentRepeater_ItemCreated(ByVal sender As Object, ByVal e As RepeaterItemEventArgs) Handles ParentRepeater.ItemCreated
Dim dv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
If dv IsNot Nothing Then
Dim repSubMenu As Repeater = TryCast(e.Item.FindControl("childrepeater"), Repeater)
If repSubMenu IsNot Nothing Then
AddHandler repSubMenu.ItemCommand, AddressOf childrepeater_ItemCommand
repSubMenu.DataSource = dv.CreateChildView("Children")
repSubMenu.DataBind()
End If
End If
End Sub
Protected Sub childrepeater_ItemCommand(ByVal source As Object, ByVal e As RepeaterCommandEventArgs)
Dim stophere As String = ""
End Sub
I put a breakpoint on stophere, and it never gets hit.
Sorry guys, I'm really confused :(
Try this:
Protected Sub ParentRepeater_ItemCreated(ByVal sender As Object, ByVal e As RepeaterItemEventArgs) Handles ParentRepeater.ItemCreated
Dim childRepeater As Repeater = DirectCast(e.Item.FindControl("childrepeater"), Repeater)
AddHandler childRepeater.ItemCommand, AddressOf childrepeater_ItemCommand
childRepeater.DataSource = "the data source for childRepeater"
childRepeater.DataBind()
End Sub
Protected Sub childrepeater_ItemCommand(ByVal source As Object, ByVal e As RepeaterCommandEventArgs)
End Sub

Dynamically generated Linkbutton does not fire Onclick event VB.Net

I have followed some of the instructions to create a new LinkButton at runtime with an event trigger and add an event handler for the LinkButton generated. I have no idea why the new LinkButton does not trigger the event added to it. Anyone please guide/correct me.
This is what I have right now.
ASPX:
<form id="myForm" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<table class="mel-table" style="text-align: center" runat="server" id="mytab1">
<tbody>
<tr>
<td>Case Number :</td>
<td>
<asp:TextBox ID="caseNumber" runat="server"></asp:TextBox>
</td>
</tr>
</tbody>
</table>
<asp:Button OnClick="btnOK1_Click" ID="btnOK1" runat="server" Text="Save" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
ASPX.VB:
Protected Overloads Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Session("tablecontent") IsNot Nothing Then
mytab1 = CType(Session("tablecontent"), HtmlTable)
End If
End Sub
Public Function checking() As Boolean
Dim caseNo As Double
Try
caseNo = Convert.ToDouble((caseNumber.Text).Trim())
Catch ex As Exception
caseNo = 0
End Try
Dim r As New HtmlTableRow
Dim c0 As New HtmlTableCell
r.Cells.Add(c0)
Dim but As New LinkButton
but.ID = caseNo
but.Text = caseNo.ToString()
AddHandler but.Click, AddressOf LinkButton1_Click
c0.Controls.Add(but)
mytab1.Rows.Add(r)
Session("tablecontent") = mytab1
Return True
End Function
Protected Sub LinkButton1_Click(sender As Object, e As EventArgs)
'My Code here
End Sub
Protected Sub btnOK1_Click(sender As Object, e As EventArgs)
If (checking()) Then
ScriptManager.RegisterStartupScript(Page, Page.GetType, "Alert", "<script type='text/javascript'>alert('Success');</script>", False)
End If
End Sub
When you click on the "Save" button, save the data in either local storage or database and try to load the page again to fill the page with the content from the storage. In this case, you can have the content on the page and so, you can utilize the events also.
Whenever you create dynamic control you have to reload it on postback. I am using method call ReloadRows() for reloading added case which i am saving in ViewState:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers="true" UpdateMode="Conditional" >
<ContentTemplate>
<asp:Table class="mel-table" style="text-align: center" runat="server" id="mytab1">
<asp:TableRow>
<asp:TableCell>Case Number :</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="caseNumber" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<asp:Button OnClick="btnOK1_Click" ID="btnOK1" runat="server" Text="Save" />
</ContentTemplate>
</asp:UpdatePanel>
--------------------------------------------------------------------------------------------------------
Public Partial Class _Default
Inherits System.Web.UI.Page
Private listCaseNo As List(Of Double) = Nothing
Protected Sub Page_Init(sender As Object, e As EventArgs)
End Sub
Protected Sub Page_Load(sender As Object, e As EventArgs)
If ViewState("ListCases") IsNot Nothing Then
listCaseNo = DirectCast(ViewState("ListCases"), List(Of Double))
Else
listCaseNo = New List(Of Double)()
End If
ReloadRows()
End Sub
Public Function checking() As Boolean
Dim caseNo As Double = 0
Try
caseNo = Convert.ToDouble((caseNumber.Text).Trim())
Catch ex As Exception
caseNo = 0
End Try
Dim r As New TableRow()
Dim c0 As New TableCell()
r.Cells.Add(c0)
Dim but As New LinkButton()
but.ID = Convert.ToString(caseNo)
but.Text = caseNo.ToString()
AddHandler but.Click, AddressOf LinkButton1_Click
c0.Controls.Add(but)
mytab1.Rows.Add(r)
listCaseNo.Add(caseNo)
ViewState("ListCases") = listCaseNo
Return True
End Function
Private Sub ReloadRows()
For Each objCase As var In listCaseNo
Dim r As New TableRow()
Dim c0 As New TableCell()
r.Cells.Add(c0)
Dim but As New LinkButton()
but.ID = Convert.ToString(objCase)
but.Text = objCase.ToString()
AddHandler but.Click, AddressOf LinkButton1_Click
c0.Controls.Add(but)
mytab1.Rows.Add(r)
Next
End Sub
Protected Sub LinkButton1_Click(sender As Object, e As EventArgs)
'My Code here
End Sub
Protected Sub btnOK1_Click(sender As Object, e As EventArgs)
If (checking()) Then
End If
End Sub
End Class

getting image src on click on image in data list

I have datalist containing images.
I have bounded these images to datalist by taking image names from database.
I just want to get src [Path of image] which user clicks on datalist.
My datalist is as following:
<asp:DataList ID="dlImages" runat="server" RepeatColumns="4">
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" Height="200px" Width="200px" runat="server" />
</ItemTemplate>
</asp:DataList>
and i have bounded it as follows:
Protected Sub dlImages_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles dlImages.ItemDataBound
If e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.EditItem Then
CType(e.Item.FindControl("ImageButton1"), ImageButton).ImageUrl = "~/ScreenMasterImages/" & e.Item.DataItem("PageName") & ".jpg"
End If
End Sub
Please help me to get src of particular image which user clicks on datasource.
I'd go for this:
Protected Sub ImageButton1_Click(sender As Object, e As ImageClickEventArgs)
Dim btn As ImageButton = sender
Dim selImage As String = btn.ImageUrl.ToString
MsgBox(btn.ImageUrl.ToString)
'Shorter:
Dim selImage As String = sender.ImageUrl.ToString
End Sub
Complete Code for testing:
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Dim ditems As New List(Of di)
For i As Integer = 0 To 10
Dim dii As New di
dii.d_Name = "x" & i
ditems.Add(dii)
Next
dlImages.DataSource = ditems
dlImages.DataBind()
End If
End Sub
Protected Sub dlImages_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles dlImages.ItemDataBound
If e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.EditItem Then
CType(e.Item.FindControl("ImageButton1"), ImageButton).ImageUrl = "~/ScreenMasterImages/" & DirectCast(e.Item.DataItem, di).d_Name & ".jpg"
End If
End Sub
Protected Sub ImageButton1_Click(sender As Object, e As ImageClickEventArgs)
Dim btn As ImageButton = sender
Dim selImage As String = btn.ImageUrl.ToString
MsgBox(btn.ImageUrl.ToString)
End Sub
End Class
Public Class di
Public Property d_Name() As String
Get
Return m_d_Name
End Get
Set(value As String)
m_d_Name = value
End Set
End Property
Private m_d_Name As String
End Class
And the asp:
<asp:DataList ID="dlImages" runat="server" DataKeyField="d_Name" DataMember="d_Name" RepeatColumns="4">
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" OnClick="ImageButton1_Click" Height="200px" Width="200px" runat="server" />
</ItemTemplate>
</asp:DataList>

DataBinding: 'System.Data.DataRowView' does not contain a property with the name 'id'

Page Load :-
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Page.Title = "Batches - " & Website
BindBatches()
Catch ex As Exception
Logger.WriteError("Error in Page_Load of Batches/batches.aspx", ex)
End Try
End Sub
This sub-routine binds batch_name in grid view
Protected Sub BindBatches()
Try
Dim ds As New DataSet()
ds = Dal.ExecuteDataset("select batch_name from tblBatch")
If Not ds Is Nothing AndAlso ds.Tables(0).Rows.Count > 0 Then
gvBatches.DataSource = ds
gvBatches.DataBind()
gvBatches.Visible = True
Else
gvBatches.Visible = False
End If
Catch ex As Exception
Logger.WriteError("Error in BindBatches of Batches/batches.aspx", ex)
End Try
End Sub
Here is gridview :-
<asp:GridView ID="gvBatches" runat="server">
<Columns>
<asp:TemplateField HeaderText="Batch Name">
<HeaderStyle Width="40px"></HeaderStyle>
<ItemTemplate>
<asp:Label ID="lblBatchName" runat="server">
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And databound event :-
Protected Sub gvBatches_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvBatches.RowDataBound
If e.Row.RowType = ListItemType.Item Or e.Row.RowType = ListItemType.AlternatingItem Then
Dim batchName As Label = e.Row.FindControl("lblBatchName")
batchName.Text = e.Row.DataItem("batch_name")
End If
End Sub
But when i debug it will show below exception on - gvBatches.DataBind()
DataBinding: 'System.Data.DataRowView' does not contain a property with the name 'id'.
I don't understand what is this id ? There is no such column in my table.
I would suggest to first set OPTION STRICT to on. It even hurts to see this code(DataItem is an Object):
batchName.Text = e.Row.DataItem("batch_name")
Instead try to cast it appropriately:
Dim row As DataRow = DirectCast(e.Row.DataItem, DataRowView).Row
batchName.Text = row.Field(Of String)("batch_name")
In your aspx file you can change you label declaration to
<asp:Label ID="lblBatchName" runat="server" Text='<%# Eval("batch_name") %>'>
and you don't need Protected Sub gvBatches_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvBatches.RowDataBound function

Add Textbox TemplateField Column To GridView Programmatically

How do I add a TextBox column to a GridView from code behind?
Use a TemplateField and add a TextBox to the ItemTemplate/EditItemTemplate.
<ItemTemplate>
<asp:TextBox ID="TxtFirstName" runat="server" Text='<%# Bind("FirstName") %>'></asp:TextBox>
</ItemTemplate>
You can bind it on the aspx as in the example above or in GridView.RowDataBound:
Private Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
Select Case e.Row.RowType
Case DataControlRowType.DataRow
Dim dr As DataRow = DirectCast(DirectCast(e.Row.DataItem, DataRowView).Row)
Dim TxtFirstName As TextBox = DirectCast(e.Row.FindControl("TxtFirstName"), TextBox )
TxtFirstName.Text = dr("FirstName").ToString
End Select
End Sub
Edit: Here is a simple example on how to add a TemplateField dynamically:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
If Not IsPostBack Then
Dim txtColumn As New TemplateField
txtColumn.ItemTemplate = New TextColumn
Me.GridView1.Columns.Add(txtColumn)
End If
End Sub
Class TextColumn
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn
Dim txt As New TextBox
txt.ID = "MyTextBox"
container.Controls.Add(txt)
End Sub
End Class
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.templatefield.templatefield.aspx

Resources