Programmatically set OnSelectedIndexChanged for a DropDownList in VB.NET - asp.net

I have tried below code but it didn't work:
DropDownList1.SelectedIndexChanged += new EventHandler ( doSub );
It is in C# not VB
When I type DropDownList1. intellisense doesn't bring the SelectedIndexChanged method
And last it complains about SelectedIndexChanged is an event and must be called by RaiseEvent
I'm trying to make ddls dynamically based on SelectedValue of each other, so I need to set the OnSelectedIndexChanged values programmatically instead of declarativly like this:
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DoSub">
</asp:DropDownList>
Thanks in advance.
Tip: Remove the AutoEventWireup="false" in #Page section to get solution to work.

Use AddHandler to attach an event handler.
Syntax:
AddHandler obj.EventName, AddressOf HandlerName
Example:
<script runat="server">
Protected Sub Page_Load(sender As Object, e As System.EventArgs)
AddHandler DropDownList1.SelectedIndexChanged, AddressOf DoSub
End Sub
Sub DoSub(sender As Object, e As System.EventArgs)
Response.Write(DropDownList1.SelectedValue)
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True">
<asp:ListItem>Foo</asp:ListItem>
<asp:ListItem>Bar</asp:ListItem>
</asp:DropDownList>
</div>
</form>
</body>

AddHandler DropDownList1.SelectedIndexChanged, AddressOf FunctionName

Related

GridView not changing to edit mode when EditIndex is set on RowEditing

I am using Visual Studio 2010, VB.NET, target framework .NET 4.0.
I have a GridView which I am binding to some object collection, with a CommandField column that should allow edit of the selected row.
I am setting the EditIndex property correctly in the RowEditing eventhandler.
The problem is: When I click the "Edit" link that is generated, nothing apparently happens, the row gets rendered again in "view mode", not "edit mode".
But if I do some random postback, like clicking my "doNothing" button, the row gets rendered in "edit mode" in the next postback.
I have managed to reproduce the problem in the following code:
ASPX:
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="MyForm.aspx.vb" Inherits="MySandBox.MyForm" %>
<%# Register Src="MyControl.ascx" TagName="MyControl" TagPrefix="uc1" %>
<!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">
<asp:GridView ID="gvInfrator" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:CommandField ShowEditButton="true" />
<asp:BoundField HeaderText="MyField" DataField="MyField" />
</Columns>
</asp:GridView>
<asp:Button ID="btnDoNothing" runat="server" Text="Just do a postback" />
</form>
</body>
</html>
Code Behind:
Public Class MyDto
Public Property MyField As String
End Class
Public Class MyForm
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.BindMyData()
End Sub
Private Sub BindMyData()
Dim myData As New MyDto
myData.MyField = "My field value"
Me.gvInfrator.DataSource = New MyDto() {myData}
Me.gvInfrator.DataBind()
End Sub
Protected Sub gvInfrator_RowEditing(sender As Object, e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles gvInfrator.RowEditing
Me.BindMyData()
Me.gvInfrator.EditIndex = e.NewEditIndex
End Sub
End Class
Am I doing something wrong? Is this a bug in .NET Framework 4? Is there any workaround?
You need to bind your data after you set the EditIndex of your GridView.
Protected Sub gvInfrator_RowEditing(sender As Object, e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles gvInfrator.RowEditing
Me.gvInfrator.EditIndex = e.NewEditIndex
Me.BindMyData()
End Sub

Dynamically Add Text Files to DDL in ASP & VB

I am looking to update one of my DDL's functionality by making it dynamically update so if the user adds more files, the drop down will pick this up.
At present my drop down list is pulling from VB code behind, as shown below:
Public Sub DDL_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim ddl As DropDownList = CType(sender, DropDownList) 'item is already dropdownlist
Dim ctl As TextBox = DirectCast(ddl.NamingContainer.FindControl("eTemplate"), TextBox)
If ddl.SelectedValue = 1 Then
ctl.Text = File.ReadAllText("e:Documents\Visual Studio 2013\Projects\Web\Templates\Down.txt")
ElseIf ddl.SelectedValue = 2 Then
ctl.Text = File.ReadAllText("e:Documents\Visual Studio 2013\Projects\Web\Templates\Up.txt")
Else
ctl.Text = ""
End If
End Sub
At the moment I have hard coded in the functionality for the VB to grab specific .txt files, how can I get this to update dynamically from a folder of .txt files?
Thanks for looking.
Here is some sample code for you. This demo uses an UpdatePanel and a Timer to refresh the DropdownList every 5 seconds.
Add a new aspx file to your Web Application and the following code:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Demo.aspx.vb" Inherits="Zpk_Test2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Asynchronous Update Demo</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="ScriptManager1" />
<asp:UpdatePanel runat="server" ID="UpdatePanel1">
<ContentTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" /><br />
<asp:Timer runat="server" ID="Timer1" Interval="5000" Enabled="true" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="DropDownList1" />
</Triggers>
</asp:UpdatePanel>
<asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Width="300" Height="250" />
</form>
</body>
</html>
This is the code-behind:
Partial Class Demo
Inherits System.Web.UI.Page
Private Const FolderName As String = "C:\Temp" '<-- replace with your folder name
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
RefreshDropDownList()
OpenSelectedFile()
End If
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
' this event is fired everytime a timer ticks.
' refresh your dropdown list here.
RefreshDropDownList()
End Sub
Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged
OpenSelectedFile()
End Sub
Private Sub RefreshDropDownList()
Dim currentSelected As String = DropDownList1.SelectedValue
DropDownList1.DataSource = IO.Directory.GetFiles(FolderName, "*.txt").Select(Function(f) IO.Path.GetFileName(f)).ToList
DropDownList1.DataBind()
DropDownList1.SelectedValue = currentSelected
End Sub
Private Sub OpenSelectedFile()
Dim fileName As String = IO.Path.Combine(FolderName, DropDownList1.SelectedValue)
TextBox1.Text = IO.File.ReadAllText(fileName)
End Sub
End Class

Understanding UpdatePanels

I am trying to understand UpdatePanels and best practise for using them.
I am using .Net4.0 with VB.Net.
The idea is to create a conversation app for a clients website and so I have control called Convo.ascx. Code added below.
<asp:UpdatePanel runat="server">
<ContentTemplate>
<h2>Conversation</h2>
<p><asp:Literal ID="lit1" runat="server" /></p>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
Convo.ascx.vb
Partial Class Convo
Inherits System.Web.UI.UserControl
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
lit1.Text = lit1.Text & "<p>" & TextBox1.Text & "</p>"
End Sub
End Class
On a load page (Default.aspx) I have:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%# Reference Control="~/Convo.ascx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:scriptmanager ID="Scriptmanager1" runat="server"></asp:scriptmanager>
<div>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Add Conversation" />
<asp:PlaceHolder ID="phConversation" runat="server">
</asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
With Codebehind Default.aspx.vb as
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddConvo()
End Sub
Private Sub AddConvo()
Dim getPh As New PlaceHolder
getPh = CType(Me.FindControl("phConversation"), PlaceHolder)
Dim ucConvo As New Convo
ucConvo = CType(LoadControl("~/Convo.ascx"), Convo)
getPh.Controls.Add(ucConvo)
End Sub
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
AddConvo()
End Sub
End Class
So the Convo I add OnLoad remains on the page after extra as been added been any convo added after load is gone once the button on Convo is hit.
So my question is, how can I have these add and remain? Eventually they will be added to database but right now I am trying to understand UpdatePanels as they will become the foundation for this app.
Is there a very good explanation of multi-use UpdatePanels anywhere?
Thanks in advance
PS, im a hobbiest so only VB responses please
The issue actually isn't with the UpdatePanel, but with ASP.NET. ASP.NET web forms uses a control hierarchy for the entire page, and you are adding the controls to the hierarchy "dynamically". Since you are doing it that way, ASP.NET requires you add the control back into the control hierarchy on every postback to the server. The UpdatePanel is a way to post back to the server, and therefore you must re-add the old user controls and new ones to that hierarchy.
Essentially the UpdatePanel was added to make AJAX easy, but you still have to work within the rules of ASP.NET.

Listbox Selection Change Event Selected Index

I am new to web building. I have the following listbox on the page. The page is enabled view state.
<asp:ListBox ID="ExamsList_ListBox" runat="server" DataTextField="Namee" viewstate="enabled"
DataValueField="ID" AutoPostBack="true" Height="213px" Width="152px"
ViewStateMode="Enabled" />
The data is data bind at run time. I ma able to see the list, but the listbox.selectedindex always results in "-1" value only even though I click the 10th one in box. could you please tell me what is wrong.
Here is the page code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body >
<form id="form1" runat="server">
<div>
<div>
<asp:ListBox ID="ExamsList_ListBox" runat="server" DataTextField="Namee" viewstate="enabled"
DataValueField="ID" AutoPostBack="true" Height="213px" Width="152px"
ViewStateMode="Enabled" />
</div>
</div>
</form>
</body>
</html>
and the code for filling in data is :
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsNothing(CType(Session("Login"), TikoClasses.Login)) Then
Response.Redirect("~/default.aspx")
ElseIf (CType(Session("Login"), TikoClasses.Login)).Admin = False Then
Response.Redirect("~/Loggedin/Welcome.aspx")
End If
ExamsList_ListBox.DataSource = DataModule.Exams_listall((CType(Session("Login"), TikoClasses.Login)).Inst_ID)
ExamsList_ListBox.DataBind()
End Sub
and selection changed even is:
Try
Dim k As Integer = ExamsList_ListBox.SelectedIndex
Dim tt As List(Of Integer) = ExamsList_ListBox.GetSelectedIndices.ToList
Dim t As Object = ExamsList_ListBox.SelectedValue
If ExamsList_ListBox.SelectedIndex > -1 Then
DataModule.GetExam(CType(Session("Login"), TikoClasses.Login).Inst_ID, ExamsList_ListBox.SelectedValue)
End If
Catch ex As Exception
End Try
Looking for help. Thanks in advance.
You need to put your bind code under !IsPostBack
if(!IsPostBack)
ExamsList_ListBox.DataSource = DataModule.Exams_listall((CType(Session("Login"), TikoClasses.Login)).Inst_ID)
ExamsList_ListBox.DataBind()
Endif
Since whenever your selection is Changed, your page_load event fired first and your selection is lost.

How do I apply AddHandler using OnCommand in ASP.NET

I've been racking my brain trying to get this to work. My event for my LinkButton isn't firing. I'm figuring that it has SOMETHING to do with ViewState and that the button is not there when it tries to fire the event after the Postback or something.
When I click the Add button,it adds the link to the page and then when I click the Diplay Time" linkbutton it should fire the event and display the CommandArgument data but it's not and i can't figure out why.
Here's my code:
<%# Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
End Sub
Protected Sub btnDelete_OnCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs)
Response.Write(e.CommandArgument)
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim btn As New LinkButton()
btn.ID = "lbn"
btn.Text = "Display Time"
btn.ValidationGroup = "vgDeleteSigner"
AddHandler btn.Command, AddressOf btnDelete_OnCommand
btn.CommandArgument = Now.TimeOfDay.ToString()
btn.EnableViewState = True
Panel1.Controls.Add(btn)
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
</div>
</form>
</body>
</html>
The reason that's happening is that your dynamic button "lbn" needs to be drawn again on post back when it's clicked because the button doesn't exist after you click it.
Basically you just have to dynamically add the button to the page again on post back of click of that button.
I would recommend having the button already on the page but visible = false and then just showing it when you click the other button.

Resources