Processing events on Dynamically Loaded User Controls - c#

I have a number of pages that I need to Dynamically Load User Controls and process events on controls on them. I have included sample code below for a trivial example.
Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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">
<div>
<asp:Button ID="BtnLoadControl" runat="server" Text="Load Control 1"
onclick="BtnLoadControl_Click" /><br />
<asp:Button ID="BntLoadControl2" runat="server" Text="Load Control 2"
onclick="BntLoadControl2_Click" />
<asp:PlaceHolder ID="ControlArea" runat="server" />
</div>
</form>
</body>
</html>
Deafualt.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void BtnLoadControl_Click(object sender, EventArgs e)
{
Control controlToAdd = Page.LoadControl("~/control1.ascx");
this.ControlArea.Controls.Add(controlToAdd);
}
protected void BntLoadControl2_Click(object sender, EventArgs e)
{
Control controlToAdd = Page.LoadControl("~/control2.ascx");
this.ControlArea.Controls.Add(controlToAdd);
}
}
Control1.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeFile="control1.ascx.cs" Inherits="control1" %>
<div style="border: 1px solid red;">Test Control
<br /><asp:Button runat="server" ID="testButton" Text="test" onclick="testButton_Click" /></div>
Control1.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class control1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void testButton_Click(object sender, EventArgs e)
{
Response.Write("Button Clicked on Control 1!");
}
}
Control2.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeFile="Control2.ascx.cs" Inherits="Control2" %>
<div style="border: 1px solid red;">Test Control 2
<br /><asp:Button runat="server" ID="testButton2" Text="test me"
onclick="testButton2_Click" /></div>
Control2.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Control2 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void testButton2_Click(object sender, EventArgs e)
{
Response.Write("Button Clicked on Control 2!");
}
}
This is a very trivial example to show what I would like to do. My actual control is more complex and has several properties that I set for the control I load as I load it (in the default.aspx.cs files event handler).
With this example what happens is when the button is clicked on one of the loaded controls, the page is re-loaded and the control is no longer there. How can I keep the control loaded as well as process any events that happen on the control?

You're asking if you can keep the control loaded in the page?
You can't keep the control loaded in the page, because the page doesn't exist! It's recreated on every request. It's created from the markup (compiled or not), and from running any code in the CodeBehind. If you want your controls to be there after a PostBack, then you need to recreate them on the PostBack. If you want to process events on those controls, then you'll have to wire the controls to event handlers when you recreate them after PostBack. Then the events will fire.

Related

How to add ASP.net and HTML Controls to the page at runtime?

I have an ASP.net WebForm. The markup is like:
<div>
<input type="text" id="input" runat="server" value=" " />
<asp:Button Text="send" OnClick="btnsend_Click" ID="btnsend" runat="server" />
</div>
This HTML is generated at runtime . The events are defined in the code behind file.
I need to add these controls at runtime. I tried to use the Literal-Control but the controls are working just like HTML Controls and not like ASP.net Controls.
EDIT:
Note: The Project type should be Website, not a web Application. Web application won't support on demand compilation where website yes, it is.
If I understood currectly, you want to take the Markup from User which contains even asp.net controls and scriplets too.
if this is the case, Follow below steps:
Create a dummy .ascx control file, like DynamicMarkup.ascx with empty content
Add this user control to the page (xxxx.aspx) where you want to show this control statically so it registered to the page
<%# Register src="~/DynamicMarkup.ascx"
tagname="DynamicMarkup" tagprefix="MyASP" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder runat="server"
ID="DynamicMarkupContainer" ></asp:PlaceHolder>
</div>
</form>
</body>
</html>
Write user input markup (may be get from database based on your criteria) to the DynamicMarkup.ascx file in page OnInit of the page (xxxx.aspx) And the create object of this DynamicMarkup
DynamicMarkup dynamicMarkup = LoadControl("~/DynamicMarkup.ascx") as
DynamicMarkup;
DynamicMarkupContainer.Controls.Add(ucSimpleControl);
I have not tested this approach, Just give a thought, With this you may get some session overwriting issue which you need handle.
Hope this will help!!
OLD:
is this the one that you are expecting? TextBox, and Button controls are available in System.Web.UI.WebControls namespace.
void Page_Load(Object sender, EventArgs e)
{
TextBox input = new TextBox();
input.Id ="input";
this.PlaceHolder.Controls.Add(input);
Button btnSend=new Button();
btnSend.Id ="btnSend";
btnSend.Text="Send";
btnSend.Click += new EventHandler(btnSend_Click);
this.PlaceHolder.Controls.Add(btnSend);
}
void btnSend_Click(object sender, EventArgs e)
{
// throw new NotImplementedException();
}
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<!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>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:PlaceHolder ID="phHolder" runat="server"></asp:PlaceHolder>
</form>
</body>
</html>
code behind :
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Init()
{
GenerateContorls();
}
protected void Page_Load(object sender, EventArgs e)
{
}
private void GenerateContorls()
{
TextBox newTxt = new TextBox() { ID = "txtsend" };
Button newBtn = new Button() { Text = "Send", ID = "btnsend" };
newBtn.Click += btnsend_Click;
phHolder.Controls.Add(newTxt);
phHolder.Controls.Add(newBtn);
}
protected void btnsend_Click(object sender, EventArgs e)
{
TextBox txt = (TextBox)this.FindControl("txtsend");
//your code
}
}
hope it helps

ASP.NET ListBox Trouble

Here is all my code:
Site.Master
<%# Master Language="C#" AutoEventWireup="true"
CodeBehind="Site.master.cs" Inherits="WebApplication1.SiteMaster" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form runat="server">
<div class="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server"/>
</div>
</form>
</body>
</html>
Site.Master.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class SiteMaster : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Default.aspx
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master"
AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="WebApplication1._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
</asp:Content>
Default.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ListBox ListBox1 = new ListBox();
ListBox1.FindControl("ListBox1");
ListBox1.Items.Add(new ListItem("Hello"));
}
}
}
Question: Why is my ListBox not populating?
When running the code I get a page with a small box that is completely empty.
I tried the following already and I will tell you the result -
Remove
ListBox ListBox1 = new ListBox();
ListBox1.FindControl("ListBox1");
Result: The name 'ListBox1' does not exist in the current context
Add a reference to ListBox1 manually into the designer.
Result: Object reference not set to an instance of an object.
To fix that error adding the line ListBox ListBox1 = new ListBox(); works, but still does not display.
Any ideas? Thanks.
You should only need...
protected void Page_Load(object sender, EventArgs e)
{
ListBox1.Items.Add(new ListItem("Hello", "H"));
}
See this link too
EDIT: Same code works for me.
To directly answer your question of why ListBox1 isn't getting populated:
protected void Page_Load(object sender, EventArgs e)
{
ListBox ListBox1 = new ListBox(); //You are creating a new local ListBox named ListBox1.
ListBox1.FindControl("ListBox1"); //You are trying to find the Control named ListBox1 that is held within the Control ListBox1 (and not doing anything with the result of the search)
ListBox1.Items.Add(new ListItem("Hello")); //You are adding a new ListItem to the local ListBox1.
}
As christiandev said, you should just be able to do this:
protected void Page_Load(object sender, EventArgs e)
{
ListBox1.Items.Add(new ListItem("Hello"));
}
I have no idea why you can't seem to access the ListBox1 on the aspx page.

Can't Access Textbox in ASP

I have a simple ASP.NET page with a button and a textbox, I want to click the button and have "Hello" appear in the textbox.
<%# Page Language="C#" AutoEventWireup="true" CodeFile="SOM.aspx.cs" Inherits="SOM" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div><br />
</div>
<asp:Button ID="MyBtn" runat="server" Text="Click" OnClick="SearchBtn_Click" />
<br />
<br />
<asp:TextBox ID="TextBox1" runat="server" Width="268px"></asp:TextBox>
in the code behind I am able to use Intellisence to autocomplete TextBox1.Text = "Hello";
but then when I try to debug, the project fails to build saying
The name TextBox1 does not exist in the current context
Is there a property that I need to set?
///Code behind
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Windows.Input;
public partial class SOM: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SearchBtn_Click(object sender, EventArgs e)
{
//TextBox1.Text = "HI";
}
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
}
}
If any of the great answers here do not work, here's another solution that once caused me a few gray hairs, especially if you're using VS 2012.
If your project is a web application, delete the designer.cs file. Then right click on the aspx file and select "Convert to Web Application".
For as great as Visual Studio is, sometimes these stupid WTF things drive me absolutely nuts.
Your aspx page is not referencing the correct code behind.
In the head of your aspx page replace with
<%# Page Language="C#" AutoEventWireup="true" CodeFile="myName.aspx.cs" Inherits="myName" %>
That should work
NOTE: I now know this isn't the problem, I but updated my answer in case it solves someone else's problem.
If you are using a namespace somewhere between your codebehind or the aspx page, you have to make it consistent.
I will use "MyProject" as a sample namespace.
namespace MyProject
{
public partial class SOM: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SearchBtn_Click(object sender, EventArgs e)
{
TextBox1.Text = "HI";
}
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
In your aspx page, change Inherits="SOM" to Inherits="MyProject.SOM".

Session data from textbox inputed by user

I have this project where I want to transfer data from textbox1 with session "sam" on the about.aspx on its label. The problem is that when I input a number, it is not shown on label. My problem is that I type something on the "Αριθμός Επιβατών:" textbox (a number for example) and after that I click submit I need to get the number on the about page next to "Ari8mos epivatwn :"
Defaultaspxcs.txt:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication4
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click2(object sender, EventArgs e)
{
string txt = TextBox1.Text;
Session["sam"] = txt;
}
}
}
Aboutaspxcs.txt:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication4
{
public partial class About : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = (string)Session["sam"];
}
}
}
Aboutaspx.txt:
<%# Page Title="About Us" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="About.aspx.cs" Inherits="WebApplication4.About" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<p>
Ari8mos epivatwn :
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</p>
</asp:Content>
https://www.dropbox.com/sh/4ftlddfhqo8n99p/gm-TNvol0S
It's likely that the content for the Label is being written twice, and not in the order your expect.
Start by familiarizing yourself with the asp.net page life-cycle
You will notice that PageLoad is called long before Render.
So, the page loads like this:
PageLoad Label text set to some number from your code
A bunch of other stuff
Render sets the Label text to "Label" instead, since that is what you have defined in your chtml.
Review this part of your code:
...
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
...
Try this instead:
...
<asp:Label ID="Label1" runat="server"></asp:Label>
...

Dynamically created textbox values losses when i click the button

I have created a TextBox dynamically, and i am getting the value of the textbox when i click the button. But the value entered in the dynamic textbox gets empty when i click the button.
Below is my ASPX Code:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Reports.WebForm1" %>
<!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">
<div>
</div>
<asp:DropDownList ID="DropDownList1" runat="server"
onselectedindexchanged="DropDownList1_SelectedIndexChanged" AutoPostBack = "true">
<asp:ListItem>Text</asp:ListItem>
<asp:ListItem>Check</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="GetTextBoxValue" />
</form>
</body>
</html>
CodeBehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Reports
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox TB = new TextBox();
TB.ID = "abc";
form1.Controls.Add(TB);
Response.Write(Request.Form["abc"]);
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
createcontrol();
}
protected void createcontrol()
{
if (DropDownList1.SelectedValue.ToLower().Trim() == "text")
{
TextBox TB = new TextBox();
TB.ID = "abc";
form1.Controls.Add(TB);
}
}
}
}
When you use dynamic controls in .NET and want their values to be accessible after postback you need to create them within the Page_Init method of the page. In essence its not working because ViewState has already been set by the time you created the controls. See this guide for detailed info on this topic https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx . To fix the problem elevate your Textbox instantiation code to the Page_Init method and all should be well.

Categories

Resources