Dynamically created Control rendered via HtmlTextWriter is not fireing events - c#

I have a simple ASP.Net page with a button and a Literal Control on it. On button click i am generating a new dynamic control (imagebutton) and rendering it via HtmlTextWriter to the Literal. On control creation i am also adding an onClick Event which is not getting fired. Here is my code:
aspx
<asp:Button ID="btnCreate" runat="server" Text="Create" OnClick="btnCreate_Click" />
<asp:Literal ID="lit" runat="server"></asp:Literal>
cs
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnCreate_Click(object sender, EventArgs e)
{
ImageButton dynBtn = new ImageButton();
dynBtn.ID = "1";
dynBtn.ImageUrl = "http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons/matte-blue-and-white-square-icons-symbols-shapes/118240-matte-blue-and-white-square-icon-symbols-shapes-power-button.png";
dynBtn.Click += new ImageClickEventHandler(dynBtn_click);
lit.Text = RenderControl(dynBtn);
}
private void dynBtn_click(object sender, ImageClickEventArgs e)
{
Page.Response.Write("hello!");
}
private string RenderControl(Control control)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter writer = new HtmlTextWriter(sw);
control.RenderControl(writer);
return sb.ToString();
}
}
The control is getting created without any errors but the event is not fireing.

Try this
lit.Controls.Add(dynBtn);

Adding your ImageButton to an ASP.NET container would make your life easier, and would be more in line with the way of doing things in the framework. You can add your button to different types of Web controls, depending on the type of HTML container that you want.
Option 1 - PlaceHolder
A PlaceHolder is not rendered as an HTML element. Its output contains only the controls that have been added to it. Among the 3 container controls presented here, it is the most similar to the Literal control.
<asp:PlaceHolder ID="container" runat="server" />
Option 2 - Panel
A Panel is rendered as as div element.
<asp:Panel ID="container" runat="server" />
Option 3 - Label
A Label is rendered as a span element.
<asp:Label ID="container" runat="server" />
Adding the control
The following statement can be used in code-behind to add the ImageButton to any of the 3 types of ASP.NET containers mentioned above:
container.Controls.Add(dynBtn);

Related

How To Pass Textbox Value Present In UserControl To Aspx Page Label By Clicking Button In UserControl

TestUC.ascx Design Code
<asp:TextBox ID="txtbox1" runat="server" ClientIDMode="Static" placeholder="Enter Some Text" ></asp:TextBox><br />
<asp:Button ID="btn1" runat="server" Text="Click" OnClick="btn1_Click" ClientIDMode="Static" />
Test.aspx Page Code
<%# Register Src="~/WebUserControls/TestUC.ascx" TagName="WebUserControlTest"
TagPrefix="uctest" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphBody" runat="server">
<asp:Label ID="lbl1" runat="server" >Label</asp:Label>
<uctest:WebUserControlTest ID="ucTest" runat="server"></uctest:WebUserControlTest>
</asp:Content>
OutPut:
I Need ..
Step1: Enter Some text In Text Box
Step2:Then I Click Click Button
[Note: This Two Controls Are Bind From UserControl]
Step3:What Text Entered in TextBox Is Show In label [Note Label Present In Aspx Page]
You will need to have a custom event & you will also need to expose the Text property of the TextBox in your UserControl, like this.
public partial class YourUserControl : UserControl
{
public String Text
{
get
{
return this.txtBox1.Text;
}
//write the setter property if you would like to set the text
//of the TextBox from your aspx page
//set
//{
// this.txtBox1.Text = value;
//}
}
public delegate void TextAppliedEventHandler(Object sender, EventArgs e);
public event TextAppliedEventHandler TextApplied;
protected virtual void OnTextApplied(EventArgs e)
{
//Taking a local copy of the event,
//as events can be subscribed/unsubscribed asynchronously.
//If that happens after the below null check then
//NullReferenceException will be thrown
TextAppliedEventHandler handler = TextApplied;
//Checking if the event has been subscribed or not...
if (handler != null)
handler(this, e);
}
protected void yourUserControlButton_Click(Object sender, EventArgs e)
{
OnTextApplied(EventArgs.Empty);
}
}
Then in your aspx page, where you have placed YourUserControl (OR you are dynamically adding it from the code behind), you can subscribe to this event like this.
protected void Page_Load(Object sender, EventArgs e)
{
if (!IsPostBack)
{
yourUserControl.TextApplied += new YourUserControl.TextAppliedEventHandler(yourUserControl_TextApplied)
}
}
You can use the custom event of the user control in your page like this.
protected void yourUserControl_TextApplied(Object sender, EventArgs e)
{
yourLabelInYourPage.Text = yourUserControl.Text;
}
And you are done...
EDIT : You can rename the Controls & Events as you like. I have used the names only for the example purpose.
EDIT : In website projects, if you want to add your user control dynamically then,
you might need to include the namespace ASP in your page, like this.
using ASP;
And add this Directive in your page in the aspx markup.
<%# Reference Control="~/PathToYourUserControl/YourUserControl.ascx" %>
other solution : create an event in the usercontrol, which is called in the button click.
Subscribe to this event in the codebehind of the aspx page. that way you can update your interface only if a value is provided.
a little more complicated, but you could re-use this logic to more complex control / parent control feature in the future.
i can add code snippet if asked
This Answer Is Prepared By Help Of #Devraj Gadhavi i Edited Some Code .
UserControl Page Design Code
<asp:TextBox ID="txtbox1" runat="server" ClientIDMode="Static" placeholder="Enter Some Text" ></asp:TextBox><br />
<asp:Button ID="btn1" runat="server" Text="Click" OnClick="btn1_Click" ClientIDMode="Static" />
UserControl Page Code
public partial class TestUC : System.Web.UI.UserControl
{
public String Text
{
get
{
return this.txtbox1.Text;
}
}
public delegate void TextAppliedEventHandler(Object sender, EventArgs e);
public event EventHandler TextApplied;
protected virtual void OnTextApplied(EventArgs e)
{
if (TextApplied != null)
TextApplied(this, e);
}
protected void btn1_Click(object sender, EventArgs e)
{
OnTextApplied(EventArgs.Empty);
}
}
Aspx Page Design Code
<%# Register Src="~/WebUserControls/TestUC.ascx" TagName="WebUserControlTest"
TagPrefix="uctest" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphBody" runat="server">
<asp:Label ID="lbl1" runat="server" >Label</asp:Label>
<uctest:WebUserControlTest ID="ucTest" runat="server"></uctest:WebUserControlTest>
</asp:Content>
Aspx Cs File Code
public partial class Test2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ucTest.TextApplied += new EventHandler(ucTest_TextApplied);
}
protected void ucTest_TextApplied(Object sender, EventArgs e)
{
lbl1.Text = ucTest.Text;
}
}
Another method ,If you don't want to expose the Text property of the TextBox in your UserControl Just use method "UserControl.FindControl("Id Of your Textbox which is present in user control")" in your Case WebUserControlTest.FindControl("txtbox1").
And below is the simpler way to register an event handler on the parent web form's code behind.
Code goes as below for parent form asxp.cs
protected override void OnInit(EventArgs e)
{
//find the button control within the user control
Button button = (Button)WebUserControlTest.FindControl("btn1");
//wire up event handler
button.Click += new EventHandler(button_Click);
base.OnInit(e);
}
void button_Click(object sender, EventArgs e)
{
TextBox txt = (TextBox) WebUserControlTest.FindControl("txtbox1");
//id of lable which is present in the parent webform
lblParentForm.Text=txt.text;
}
Also, you can achieve this using JavaScript like below (given your code above):
<script type="text/javascript">
function getUCTextboxValue() {
let txtName = document.getElementById('<%=ucTest.FindControl("txtbox1").ClientID %>');
let lbl = document.getElementById('<%=lbl1.ClientID %>');
lbl.innerText = txtName.value
}
Also, from the parent page, you can add a HiddenField and save the textbox value on it (using the JavaScript code above) then catch its value from code behind.

ASP.NET Button event is not raised in Web User Control

I have a ASP.NET user control, which contains a Telerik Report Viewer plus a button (server control).
I need to handle some stuff inside the click event of the button, but the event does not seem to fire.
Does anyone know why this is the case?
Here is the HTML directives inside the UserControl:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ReportControl.ascx.cs" Inherits="TelerikReportCustomRetrive.UserControl.ReportControl" %>
Here is the markup inside the UserControl:
<form runat="server" id="form1">
<telerik:ReportViewer ID="ReportViewer1" runat="server" Height="461px" ShowDocumentMapButton="False" ShowHistoryButtons="False" ShowNavigationGroup="False" ShowParametersButton="False" ShowPrintPreviewButton="False"></telerik:ReportViewer>
<asp:Button runat="server" ID="btnNav" OnClick="btnNav_Click" />
And the code behind code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var instanceReportSource = new InstanceReportSource
{
ReportDocument =
new TheReport()
};
ReportViewer1.ReportSource = instanceReportSource;
}
}
protected void btnNav_Click(object sender, EventArgs e)
{
Response.Write("Button Fired!");
}
Delete the if(!PostBack) statement. You should always initialize the control, not only if page is not post back.

Not able to visible button asp.net

I am not able to visible my button on another button click event.
.aspx
<asp:Button ID="btnActivate" runat="server" SkinID="skinLoginButton"
Text="Activate" ToolTip="Activate" CausesValidation="true"
ValidationGroup="UserAuthentication" onclick="btnActivate_Click" />
<asp:Button ID="btnhomepage" Visible="false" runat="server"
Text="Goto Homepage" CssClass="cssLoginButton" onclick="btnhomepage_Click"/>
.cs
#region btnActivate_Click
protected void btnActivate_Click(object sender, EventArgs e)
{
this.btnhomepage.Visible = true;
}
#endregion
I use this.btnhomepage.Visible = true; in .cs file.
what's wrong in my code or declearation?
<asp:Button ID="btnhomepage" Visible="false" runat="server"
Text="Goto Homepage" CssClass="cssLoginButton" onclick="btnhomepage_Click"/>
when using visible attribute in the mark-up you are forcing your control to be visible=false and stay false forever. asp.net engine render asp.net controls into html control in asp.net page life cycle at Render stage. even you had changed the control property in any code behind event
Solution: Don't use makup attribute when setting control behaviour dynamicllay
page life cycle link:
http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx
http://www.codeproject.com/Articles/73728/ASP-NET-Application-and-Page-Life-Cycle
Remove the visible property from the btnhomepage button and make it invisible from Page_Load
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
this.btnhomepage.Visible = false;
}
}
Try this
btnhomepage.Visible = true;
btnhomepage.Enabled = true;
btnhomepage.Style.Add("display", "block");

Retrieve contents of HtmlGenericControl inside ASCX WebControl

I have an HtmlGenericControl which is a simple DIV with runat=server
This Control is embedded inside of an ASCX WebControl which resides on multiple pages. At Page_Load this element is populated by a repeater that is data-bound to database data that is Page Specific.
The trouble I'm having is ASCX WebControls don't seem to read the contents of their own elements very easily.
So far this has failed:
How do I get the HTML output of a UserControl in .NET (C#)?
I'm looking for a way to get the contents of the HtmlGenericControl inside of a button click. How would I do that?
Simplifying previous question. Retrieve HTML of specific element in ASCX
OK, I got it working (I think...)
Output
ASPX Code behind
public override void VerifyRenderingInServerForm(Control control)
{
//base.VerifyRenderingInServerForm(control);
}
ASPX markup
%# Page EnableEventValidation="false" .....
User control code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
var d = new QuestionsContext().GetQuestions();
this.repeater.DataSource = d;
this.repeater.DataBind();
}
}
protected void getContent_Click(object sender, EventArgs e)
{
var sb = new StringBuilder();
this.generic.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
string s = sb.ToString();
this.Trace.Warn(Server.HtmlEncode(s));
this.message.Text = Server.HtmlEncode(s);
}
User control markup
<div runat="server" id="generic">
<asp:Repeater runat="server" ID="repeater" >
<ItemTemplate>
<%# Eval("QuestionText") %>
</ItemTemplate>
</asp:Repeater>
</div>
<br />
<asp:Button Text="Get content" ID="getContent" runat="server" OnClick="getContent_Click" />
<br />
<asp:Label ID="message" runat="server" />

ASP.net UpdatePanel dynamically using C# code

I have a custom usercontrol that has some Asp.net code. I would like to write the same code but with C#.
The problem is that i don't know how to put a repeater and some buttons into the ContentTemplate.
The Asp.net Code :
<asp:UpdatePanel runat="server" ID="up">
<ContentTemplate>
<n2:Repeater ID="rpt" runat="server">
<ItemTemplate></ItemTemplate>
</n2:Repeater>
<asp:LinkButton runat="server" ID="btnFirst"
Visible="false" Enabled="false" Text="<<" OnClick="btnFirst_Click" />
</ContentTemplate>
</asp:UpdatePanel>
So how could I write this chunk in C# code? To be precise, how could I insert the repeater and the Linkbutton into the ContentTemplate.
Note : I don't want to use the LoadTemplate to do it.
Edit
I have tried ContentTemplateContainer.Controls.Add():
private UpdatePanel up = new UpdatePanel();
private Repeater rpt = Repeater();;
public Paging{
//Add repeater to updatePanel
up.ContentTemplateContainer.Controls.Add(rpt);
AsyncPostBackTrigger apb3 = new AsyncPostBackTrigger();
apb3.ControlID = "btnFirst";
apb3.EventName = "Click";
//Add Triggers to updatePanel
up.Triggers.Add(apb1);
//Create buttons
btnFirst = new LinkButton();
btnFirst.Visible = false;
btnFirst.Enabled = false;
btnFirst.Text = "<<";
btnFirst.Click += new EventHandler(btnFirst_Click);
//Add buttons to update panel
up.ContentTemplateContainer.Controls.Add(btnFirst);
}
protected void Page_Load(object sender, EventArgs e)
{
rpt.ItemTemplate = LoadTemplate("~/UI/Templates/NewsEvent.ascx");
....
}
I have an error caused by the first line on Page_Load :
Databinding methods such as Eval(), XPath(), and Bind() can only be used in controls contained in a page.
This is NewsEvent.ascx:
<img src='<%# Eval("ImageThumbnail") %>' alt="" />
you cant do this with ITemplate types ... i had a similar problem trying to clone a tabpanel in a tabcontainer control ... i already had a hidden tabpanel and all i wanted to do was create a new tabpanel and basically instantiate the ITemplate from the hidden one in the new one.
The problem is ITemplate ... it's not very dynamic for code behind interactions i would suggest putting that markup on the page as you already have and setting visible = false on the parent then when you need to databind and show the hidden panel.
getting the initial bind to work isn't the problem ... its the postback handling ...
Ajax TabContainerTabPanels Break postbacks

Categories