Single event handler for multiple links/buttons on ASP.NET - asp.net

I have a dropdown list that contains a collection of names. My entire names list is very large (over 2,000) so I would like to pair down the names in the drop down list to those starting with the same letter.
To do this I would like to have 26 links all on the same line, one for each letter in the alphabet ..
A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
The idea being that the user clicks on the letter they are interested in and the stored procedure that obtains the list of names is re-executed to only grab those names starting with the letter that was clicked and then the resulting dataset is rebound to the dropdown list.
What is vexing me is how to handle creating all the "Click Events" necessary to deal with the user "clicking" on a link. I could create 26 different event handlers, one for each link, but I have to believe there is a simpler way I am not seeing.
Form demonstration here is the click event for one link, the letter "A" ...
Protected Sub lnkLetterA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkLeterA.Click
Call LoadNamesIntoDropDown("A")
End Sub
Is there a way to create one event handler that could handle all 26 links? Thank you.
P.S. C# or VB.NET examples are fine. I just happen to be using VB.NET in this case.

You can reuse the same click handler a simple example
protected void HandleLinkClick(object sender, EventArgs e)
{
HyperLink link = (HyperLink)sender;
LoadNamesIntoDropDown(link.Text);
}
However, there are loads of autocomplete style solutions you can use. A free one from MS
http://www.asp.net/ajax/ajaxcontroltoolkit/samples/autocomplete/autocomplete.aspx

Of course you can have one handler to rule them all. Just connect the Click event of all the links to the same method.
Do you create the links dynamically in code-behind, or have you created them in the designer? If it is done in the designer:
Select a link
In the property grid, switch to the event view
In the click event, select your event handler from the dropdown list
Repeat for all links
In the event handler, use the sender argument to examine which of the links that was clicked, and act accordingly.

As per your example use:
Protected Sub lnkLetter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkLeterA.Click, lnkLeterB.Click, lnkLeterC.Click //etc
Call LoadNamesIntoDropDown(CType(sender, LinkLabel).Text)
End Sub

Related

asp.net/vb.net System.Web.UI.WebControls.RepeaterItemEventArgs question

I'm really new to asp.net so please forgive me if this seems like a really basic question. I have an asp.net page that contains a repeater. Here's the code:
<div class="formRow">
<asp:Repeater ID="uxStudentFormActive" runat="server">
<ItemTemplate>
<span style="font-weight:bold;" ><asp:Literal ID="uxFormName" runat="server" Text="#" /></span><br />
<asp:TreeView ID="uxFormHistoryList" runat="server" Target="_blank" />
</ItemTemplate>
</asp:Repeater>
</div>
Here's the sub in my vb.net page that handles uxStudentFormActive.ItemDataBound:
Protected Sub uxStudentFormActive_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles uxStudentFormActive.ItemDataBound
Dim dr As DataRowView = CType(e.Item.DataItem(), DataRowView)
If Convert.ToInt32(dr("FormId")) = 29 Then
...
End If
End Sub
I'm not exactly sure how the aspx page interacts with the vb.net page. My question is how do I find out how where the values for e that are being passed to the sub uxStudentFormActive_ItemDataBound in my vb.net page are coming from? Thanks in advance.
From this MSDN article on handling events in ASP.Net:
Events [in ASP.Net] are based on the delegate model...A delegate is a type that holds a reference to a method... An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as a button click, or it could be raised by some other program logic, such as changing a property’s value. The object that raises the event is called the event sender... Data that is associated with an event can be provided through an event data class.
In your case, the event data class is RepeaterItemEventArgs.
To respond to an event, you define an event handler method in the event receiver. This method must match the signature of the delegate for the event you are handling. In the event handler, you perform the actions that are required when the event is raised, such as collecting user input after the user clicks a button. To receive notifications when the event occurs, your event handler method must subscribe to the event.
Reading that, you might say "Well that's well and good, but what does it mean?" In your project, you probably have a property set at the top of your .aspx page named AutoEventWireup. It's probably set to true. This property does what it seems: it automatically wires up your events so that you don't have to. This is how your .aspx page knows how to interact with the code-behind file.
On your .aspx page, you have your repeater control. On your code-behind file, you have your event handler method. Because you have AutoEventWireup set to true, those two things are automatically linked together as long as your event handler method signature matches the signature of the delegate for that event. In this case, that event is ItemDataBound.
To your original question, where do the values of e come from? From the sender!
Protected Sub uxStudentFormActive_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles uxStudentFormActive.ItemDataBound
In this method signature, you have two parameters: sender, and e. As described in the quote above, the sender is the object that raises the event. In your case, this is the RepeaterItem. Since the repeater likely contains many of these objects, the event can be raised multiple times. The event argument, e, is generated from the sender, or the RepeaterItem that was databound and caused the event to fire.
You can read more about the RepeaterItemEventArgs and the data available within on the MSDN.
As a side note, you can set AutoEventWireup to false and manually wireup the events as described in depth in the link to the MSDN article on the AutoEventWireup property.
Thanks to #Jack for giving me more insight into this. I'm sorry if my OP wasn't more clear, I did understand that the values were coming from the .aspx page, what I was actually asking is where the values that are being passed as e into my sub are being set, how e is being populated with data. The answer came from looking at the repeater id for the repeater I'm asking about, uxStudentFormActive. When I searched for this repeater id my vb.net code behind I found that the data source for the it was defined and bound in the Page_Load sub. Tracking this down lead me to a stored procedure in my database that is being passed session data and e is being set to the results of the stored procedure.

Making combobox_selectedIndexChanged work

I have a web page that on page load loads data into drop down lists and the user has the option to change the values if they wish too. How do I make it so everytime they change the value it will save it and resend it to the database? So far all I have is this:
Private Sub cboCure_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboCure.SelectedIndexChanged
cboCure.SelectedItem.Text = CStr(sender)
...database functions using cboCure.SelectedItem.Text
End Sub
I don't know if this is enough information to help out at all, if it's not just lemme know... I don't really know what else to put in this one.
Set autopostback property of your combobox to true. So that, whenever a change happens; you can check if if(ispostback) and have your code to do the insertion of changed data in DB.

How to register data for validation using RegisterForEventValidation in asp.net

I would like to know the method of using RegisterForEventValidation in asp.net
My problem is this.
If I enable eventvalidation, then changing the controls using javascript and then posting the information back to the server later on throws up an error.
But If I disable event validation, the data present/selected in the controls is not available in the event handlers in code behind.
So, how should one resolve such issues?
Also, are there are any good articles that explain the issue and a resolution in detail? Tried googling. Came across many articles. But nothing that matched my expectations.
A small progress.
If I do the below, the event validation error goes away, but am not able to get the selected value in the code behind on button click (after selecting "1" in the dropdown, since for now I have registered only that value)
I get a runtime error - Unable to convert from string to double when I try accessing the selected value in drop down in code behind (The reason I believe is that no value is passed in the first place).
Any idea on what might be going wrong here!? Thanks!
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
Page.ClientScript.RegisterForEventValidation(Me.ddldobddId.UniqueID, "1")
MyBase.Render(writer)
End Sub
Protected Sub btnId_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnId.Click
If CType(Me.ddldobddId.SelectedValue, Integer) = 0 -> Throws the error
End Sub
You've pretty much got it. The DropDownList.SelectedValue is always going to be a System.String type.
You must convert the String to an Integer in your btnId_Click method.
Protected Sub btnId_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnId.Click
Dim convertedSelectedValue As Integer
convertedSelectedValue = Convert.ToInt32( Me.ddldobddId.SelectedValue )
End Sub

How do I make a Wizard control save the data after each step?

Is there a way that i can save data on each step in wizard control.
I want to save data when user clicks next button on each step.
I would like to save them to database , so that i can retrieve them back if user has opted to close and complete steps later without clicking finish button
In your code-behind, you can capture the "Active Step Changed" event and do whatever you want:
Protected Sub AddEmployeeWizard_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles AddEmployeeWizard.ActiveStepChanged
'save your data here
End Sub
If you just want to save on a click of the Next button, you could instead do
Protected Sub myWizard_NextButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles myWizard.NextButtonClick
'save your data here
End Su
b
You can save data to Session or ViewState objects.
Also you can add you saving logic in wizard events: ActiveStepChanged, CancelButtonClick, FinishButtonClick, NextButtonClick, PreviousButtonClick, SideBarButtonClick.
In ASP.NET you can probably stick it in the Session variable.
In an WPF or Winforms app, you could just put it in a variable in memory, and if these are settings for your program, you could save them to an XML file.

Add Multiple User Control of the Same Type to a Page

Similar questions to this one have been asked but none seem to address my exact situation here's what I am trying to do.
I have a user control that manages student info. i.e. FirstName, LastName, Address etc.
I have a webpage/form that has a button on it. "Add Student". What I want to accomplish is for a new StudentInfo control to be added to the webform after each click.
My current code looks something like this
Private Sub btnAddStudent_Click(sender as object, ByVal e As System.EventArgs)
Dim lStudentInfo as Control
LoadControl("~/StudentInfo.ascx")
Me.placeholder1.controls.add(lStudentInfo)
End Sub
With this code only one StudentInfo control is added and upon pressing the "Add" button again a new StudentInfo control isnt added below the first one and the text/data entered within the first control is cleared.
Thanks in advance for any assistance.
What is happening is that every time you do a postback your previous control was lost. Remember, every postback uses a brand new instance of your page class. The instance you added the control to last time was destroyed as soon as the http request finished — possibly before the browser even finished loading it's DOM.
If you want a control to exist for every postback you have to add it on every postback.
Additionally, if you want ViewState to work for the control you need to add it before the Load event for the page. This means either on Init or PreInit.
Private Sub btnAddStudent_Click(sender as object, ByVal e As System.EventArgs)
Me.placeholder1.controls.add(LoadControl("~/StudentInfo.ascx"))
Session("NewStudentControls") += 1
End Sub
Protected Sub Page_Init(sender as object, e as system.eventargs)
For i As Integer = 1 To Session("NewStudentControls")
Me.placeholder1.controls.add(LoadControl("~/StudentInfo.ascx"))
Next
End Sub

Resources