Event of dynamically created Control not firing - asp.net

I'm having a problem with a Web Control that is dynamically created and inserted in my page. I create a couple of LinkButtons, depending on the data of the search that was made, and I'm trying to add an Event Handler to each of the Buttons, so it would filter the result.
The controls are initialized properly, but the event is never fired.
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
Controls.Clear()
Dim btn As Controls.LocalizableLinkButton
For Each element As Generic.KeyValuePair(Of String, ResultFilterData) In m_list
btn = New LocalizableLinkButton
btn.ID = m_Name & "$lnk" & count
btn.Label = element.Value.Label.Append(" (" + CStr(element.Value.Count) + ")")
btn.CommandArgument = element.Value.Key
AddHandler btn.Click, AddressOf Me.btn_Click
Controls.Add(btn)
Next
End Sub
Since this code is in Page_Init all the controls should be recreated on a postback. (The LocalizableLinkButton is just an extension of a LinkButton to add multilingual features to the text).
The problem is that the method btn_Click is never called. The Link Buttons are properly initialized on the callback, with the same ID's as before. But the event doesn't fire.
I'm using ASP.Net 2.0
Any ideas?

I finally figured out the problem ASP.NET had with my Link Buttons.
The error was in using a '$' sign in my ID for each LinkButton. ASP.NET apparently uses the $ sign to build the control hierarchy when it creates the Postback Javascript. Therefore it thinks that the LinkButtons are nested within a control that does not exist. And so the events aren't fired of course.
Once I removed the $ signs it worked properly.

You probably want to put this piece of code in the Page_Load and see. It's generally advised not to access controls in this Page_Init as there is no guarantee of the controls been created at this stage.
I'm no VB guy but i put this into the codebehind of the default.aspx and it works fine.
protected void Page_Load(object sender, EventArgs e)
{
Button button = new Button();
button.Click += new EventHandler(button_Click);
button.Text = "test";
Form.Controls.Add(button);
}
void button_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}

Related

Using panels in ASP.net

i created a textbox, a button and a panel in a page. So my aim is to create links which will be put inside a panel. However, it turns out that every time i add another one, it seems to replace the previously created link. Is there a way to just add the links, not replacing previously created links? I really don't have a background that much in ASP.
This is the code I researched.
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim link As New HyperLink()
Dim ltr As New Literal()
link.Text = TextBox1.Text
link.NavigateUrl = "Default.aspx?field1=" + TextBox2.Text + " "
ltr.Text = "<br/>"
Panel1.Controls.Add(ltr)
Panel1.Controls.Add(link)
Please help me. Thanks!
As said by #Rex, when post back occurs dynamically controls will be removed from the page until we retain them in Init Event.
While adding controls to PlaceHolder, save the same data like ID, Text..etc. in a object like session variable and retrieve the same data in Page Init event and add to the place holder.
protected void Page_Init(object sender, EventArgs e)
{
// Retrieve from session variable and add the same data to the place holder.
}

.NET UserControls First time load or subsequent reload flag

I am sure everyone who programmed with user controls for asp.net came across situations where you needed a certain way to check whether a user control has been loaded for the first time or it has been re-loaded. Has anyone come up with any other solutions other than setting hidden "currentOpenControl" flag(s). If you are wondering as to do I need to check whether control is open for first time or re-open again, then one of the big reasons is databinding. When the control is open for first time, that is when I want to databind, afterwards on re-open, if I databind again I will lose any changes user might have added.
So I am just wondering if anyone has a more elegant solution than setting flags whether control is open or not.
Thanks
The only way I've ever managed to do this is by using the ViewState...
Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
If ViewState["postBack"] Is Nothing Then
' Do everything you'd normally do with Page.IsPostBack
ViewState["postBack"] = true
End
End Sub
Or for C#...
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["postBack"] == null)
{
// Do everything you'd normally do with Page.IsPostBack
ViewState["postBack"] = true;
}
}
You can get using this, its in VB.NET convert to c#
Private currentPage As Page = HttpContext.Current.Handler
If (Not currentPage.IsPostBack) Then
End if

SelectedIndexChanged for programmatically created dropdownlist in ASP.NET fires multiple times

Consider the following:
dim dropdownlist1 as new dropdownlist
dim dropdownlist2 as new dropdownlist
dim dropdownlist3 as new dropdownlist
dropdownlist1.AutoPostBack = true
dropdownlist2.AutoPostBack = true
dropdownlist3.AutoPostBack = true
AddHandler dropdownlist1.SelectedIndexChanged, AddressOf SomeEvent
AddHandler dropdownlist2.SelectedIndexChanged, AddressOf SomeEvent
AddHandler dropdownlist3.SelectedIndexChanged, AddressOf SomeEvent
Edit:
I want an event to fire no matter which dropdown is selected.
Edit:
The SomeEvent fires as expected when any of the dropdown's selection is changed. However if say DropdownList2 has a selection made then I make a selection with either DropDownList1 or DropdownList3, then SomeEvent fires again. What is causing this behavior and how do I get just a single raising of that event?
I suspect that when the viewstate for the dynamcially created dropdownlists is restored and the selection restored, then the event is fired because technically the selected index did change when the control was recreated. The reason I suspect this is that the event fires the for each dropdownlist...
The event will fire when the value of that property is changed programatically after the event is wired up. This is likely the cause of multiple calls of the function. This is why you need to add any event handlers after the viewstate is loaded. Try looking at the stack trace for each time the method is called to find where this is happening.
This is what I have and it works fine (Sorry I am a C# guy)
protected void Page_Load(object sender, EventArgs e)
{
DropDownList objlist1 = new DropDownList();
DropDownList objlist2 = new DropDownList();
DropDownList objlist3 = new DropDownList();
objlist1.Items.Add("aaa");
objlist1.Items.Add("bbb");
objlist2.Items.Add("cc");
objlist2.Items.Add("ddd");
objlist3.Items.Add("eee");
objlist3.Items.Add("fff");
objlist1.AutoPostBack = true;
objlist2.AutoPostBack = true;
objlist3.AutoPostBack = true;
objlist1.SelectedIndexChanged += new EventHandler(objlist1_SelectedIndexChanged);
objlist2.SelectedIndexChanged += new EventHandler(objlist1_SelectedIndexChanged);
objlist3.SelectedIndexChanged += new EventHandler(objlist1_SelectedIndexChanged);
form1.Controls.Add(objlist1);
form1.Controls.Add(objlist2);
form1.Controls.Add(objlist3);
}
void objlist1_SelectedIndexChanged(object sender, EventArgs e)
{
Response.Write("change happened");
}
Everytime the drop down changes it writes Change happened (checked with break point and it happens only once)
Not sure if this helps, but where in the page lifecycle are you creating the controls?
I usually like to call EnsureChildControls during Page Init, so all controls are created before ViewState is loaded, and definitely before post back processing.

Handling Web User Control error on asp.net page

How do you handle the Web User Control event? I notice my custom web user control have a event call OnError but it never fire when i tweak the control to fail. The control is basically a custom gridview control. I search for web user control event handling over the net but i haven't find a article that address what i looking for. Can someone do a quick explanation or point me to the right direction?
thank
You didn't mention what flavour of ASP.NET, so I'll make the assumption of VB - C# is largely the same with the exception of how the event handler is attached.
The normal pattern you would expect to see is something along these lines:
User Control "MyUserControl" CodeBehind
Public Event MyEvent(ByVal Sender As Object, ByVal e As EventArgs)
Private Sub SomeMethodThatRaisesMyEvent()
RaiseEvent MyEvent(Me, New EventArgs)
End Sub
Page Designer Code
Private WithEvents MyUserControl1 As System.Web.UI.UserControls.MyUserControl
Page or other Control that wraps MyUserControl instance CodeBehind
Private Sub MyUserControlEventHandler(ByVal Sender As Object, ByVal e As EventArgs) _
Handles MyUserControl.MyEvent
Response.Write("My event handled")
End Sub
In some instances, you see something called Event Bubbling which doesn't follow this kind of pattern exactly. But in the basic sense of handling events from a user control to a wrapper control or the page it sits in, that's how you would expect it to work.
I had an issue with a custom control that was throwing exceptions which were not firing Error event. Thus I could not catch exceptions from this control and display appropriate message in the ASP.NET page.
Here is what I did. I wrapped the code in the custom control in a try..catch block and fired the Error event myself, like this:
// within the custom control
try
{
// do something that raises an exception
}
catch (Exception ex)
{
OnError(EventArgs.Empty); // let parent ASP.NET page handle it in the
// Error event
}
The ASP.NET page was handling the exception using the Error event like this:
<script runat="server">
void MyCustomControl_Error(object source, EventArgs e)
{
MyCustomControl c = source as MyCustomControl;
if (c != null)
{
// Notice that you cannot retrieve the Exception
// using Server.GetLastError() as it will return null
Server.ClearError();
c.Visible = false;
// All I wanted to do in this case was to hide the control
}
}
</script>
<sd:MyCustomControl OnError="MyCustomControl_Error" runat="server" />

how to raise event from dynamically created usercontrol

How do I raise an event from a user control that was created dynamically?
Here's the code that I'm trying where Bind is a public EventHandler
protected indDemographics IndDemographics;
protected UserControl uc;
override protected void OnInit(EventArgs e)
{
uc = (UserControl)LoadControl("indDemographics.ascx");
IndDemographics.Bind += new EventHandler(test_handler);
base.OnInit(e);
}
I get a null object for IndDemographics. Can anyone point me to a complete code sample?
Thanks in advance...
First off, you'll need to make sure that you have the event defined in your usercontrol's code.
for example:
public class MyUserControl
Inherits UserControl
Public Event Bind(sender as object, e as EventArgs)
public sub SomeFunction()
RaiseEvent Bind(me, new EventArgS())
End Sub
End Class
After this, then you can bind to the Event. Now,for your other issue, are you loading this control dynamically or is it declared on your ASPX side? If it's on your ASPX side, then you don't need the LoadControl, as declaring an object as Runat=Server on the ASPX side instantiates an instance of said class.
If not, then you'll need to make sure you're using the Virtual Path for the location of the ASCX file. (in your example, you'd use "~/indDemographics.ascx" if the ASCX was at the root of the website). At this point you'd need to add it to the page (or a placeholder or some other container object).
Regardless, of which way you instantiate an instance of the UserControl, you then associate the Event Handler to the Event of the instance of the class. For example:
Dim btn As New Button;
AddHandler btn.Click, AddressOf MyButtonClickEventHandler
Now, for the reason that you're getting a NULL reference in the example code.
When you use the LoadControl reference, then the instance of your object is in the UC variable. In the example, you declare two objects, UC as a type of UserControl and indDemographics as a type of indDemographics.
When you use the LoadControl, you're instantiating an instance of indDemographics and assigning it to UC. When you try to assign the event handler to the IndDemographics variable, it has never actually been instantiated.
Ultimately, your code should look more along these lines:
protected indDemographics IndDemographics;
override protected void OnInit(EventArgs e)
{
indDemographics = LoadControl("~/indDemographics.ascx");
IndDemographics.Bind += new EventHandler(test_handler);
base.OnInit(e);
}
I see it (IndDemographics) declared but never actually created, so I'd expect it to be null with just this code.
Thanks to Stephen for getting me on the right track. Here's the final working code in C#:
protected indDemographics IndDemo;
override protected void OnInit(EventArgs e)
{
Control c = LoadControl("~/indDemographics.ascx");
IndDemo = (indDemographics) c;
IndDemo.Bind += new EventHandler(test_handler);
place1.Controls.Add(IndDemo);
base.OnInit(e);
}
It's important to cast the generic control into the indDemographics class. After that everything else works fine.

Resources