ASP.net UpdatePanel dynamically using C# code - c#

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

Related

Dynamically created Control rendered via HtmlTextWriter is not fireing events

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);

Creating an asyncpostback from a control inside a repeater

I have a repeater whose ItemTemplate contains a PlaceHolder that I add input controls (ListBox, TextBox, CalendarExtender etc.) to on ItemDataBound:
<asp:UpdatePanel ID="ReportParameterUpdatePanel" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Repeater ID="ReportParameterEditRepeater" OnItemDataBound="ReportParameterEditRepeater_ItemDataBound" runat="server">
<ItemTemplate>
<asp:PlaceHolder runat="server" ID="ParameterEntryPlaceholder"></asp:PlaceHolder>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
How can I generate an asyncpostback from one of these TextBoxes inside the repeater (on TextChanged)?
The control is created dynamically and I only want to create the postback under certain conditions, so it needs to be done from code behind.
I have tried:
OnItemCommand (but this appears to be just for buttons)
ScriptManager.RegisterAsyncPostBackControl (doesn't seem to do anything on TextChanged)
UpdatePanel.Triggers.Add(new AsyncPostBackTrigger ...) (unable to find the TextBox as it is inside the repeater)
In ReportParameterEditRepeater_ItemDataBound you will need to assign a unique ID to each control, and then bind the text changed event. I then like to store those in session. Then add it to your placeholder.
Below is how I did it in my site for a button click event:
TemplateControls_Headline ctrl = (TemplateControls_Headline)LoadControl("~/Controls/TemplateHeadline.ascx");
ctrl.ID = "MyCtrl_" + CMSSession.Current.AddedTemplateControls.Count;
ctrl.Remove.Click += new EventHandler(RemoveItem_OnClick);
MySession.Current.AddedTemplateControls.Add((Control)ctrl);
PlaceHolder ph = accAddTemplates.FindControl("phAddTemplateControlsArea") as PlaceHolder;
ph.Controls.Add(ctrl);
Then, in your OnInit of the page, you have to re-bind everything from the viewstate since you are creating them dynamically, this is where the unique id you created comes in (this is mainly for postbacks):
protected override void OnInit(EventArgs e)
{
PlaceHolder ph = accAddTemplates.FindControl("phAddTemplateControlsArea") as PlaceHolder;
int counter = 0;
foreach (UserControl ctrl in MySession.Current.AddedTemplateControls)
{
ctrl.ID = "MyCtrl_" + counter;
ctrl.Remove.CommandArgument = counter.ToString();
ctrl.Remove.Click += new EventHandler(RemoveItem_OnClick);
counter++;
ph.Controls.Add(ctrl);
}
base.OnInit(e);
}

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");

Lazy loading tabs with user controls

I want to use lazy loading of tabs in AJAX tab container. I have implemented it. But the problem that I am facing is that when I click a button or fire any event in that user control, it is not fired; nothing happens.
<asp:TabContainer runat="server" ID="TabContainerUp"
ActiveTabIndex="0" AutoPostBack="true" OnActiveTabChanged="TabContainerUp_ActiveTabChanged">
<asp:TabPanel ID="tab1" runat="server">
<HeaderTemplate>
<img src="images/uc1.png" alt="" />
</HeaderTemplate>
<ContentTemplate>
<asp:Panel ID="pnlUC1" runat="server">
</asp:Panel>
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="tab2" runat="server">
<HeaderTemplate>
<img src="images/uc2.png" alt="" />
</HeaderTemplate>
<ContentTemplate>
<asp:Panel ID="pnlUC2" runat="server">
</asp:Panel>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
codebehind:
protected void TabContainerUp_ActiveTabChanged(object sender, EventArgs e)
{
string tabName = TabContainerUp.ActiveTab.ID;
getActiveTab(tabName);
}
public void getActiveTab(string tabName)
{
UserControl uc;
//uc.
switch (tabName)
{
case "tab1":
pnlUC1.Controls.Clear();
uc = Page.LoadControl("~/Controls/UC1.ascx") as UserControl;
pnlUC1.Controls.Add(uc);
break;
case "tab2":
pnlUC2.Controls.Clear();
uc = Page.LoadControl("~/Controls/UC1.ascx") as UserControl;
pnlUC2.Controls.Add(uc);
break;
}
}
You need to recreate dynamically created controls on every postback in Page_Load at the latest, with the same ID as before. So you can load and add them to your panels in ActiveTabChanged, but you need to recreate them in the next postback in Page_Init/Page_Load. Therefor you need to store somewhere what to recreate (f.e. in Session).
But i assume that you're making things more complicated than necessary, you could simply create these UserControls even declaratively (on aspx) with an initial Visible state of false. Then you only need to switch visibility of the controls as necessary in ActiveTabChanged.
Note: invisible serverside webcontrols will not be rendered at all to the client and no ViewState will be saved. So there's no disadvantage in declaring them.
Lazy-Load does not mean that you create these controls as late as possible but it means that you databind them as late as possible. So never bind them to the database from page_load (f.e. in the UserControl), but only from methods that will be called when necessary from the page(here from ActiveTabChanged). Therefor you could implement a public method BindData in your UserControl UC1.
Here's a simple example:
switch (tabName)
{
case "tab1":
UC1_1.Visible = true;
UC1_1.BindData();
UC1_2.Visible = false;
break;
case "tab2":
UC1_1.Visible = false;
UC1_2.Visible = true;
UC1_2.BindData();
break;
}
and in your UserControl
public void BindData()
{
// put here all your databinding stuff
// that is in page_load now ...
}
This is probably the best tutorial on lazy-loading ajax TabPanels:
http://mattberseth.com/blog/2007/07/how_to_lazyload_tabpanels_with.html

ASP.NET Panel FindControl within DataList to change property C#

I'm new to this ASP.NET stuff. In my page I have a Datalist with a FooterTemplate. In the footer I have a couple panels that will be visible depending on the QueryString. The problem I am having is trying to find these panels on Page_Load to change the Visible Property. Is there a way to find this control in the Page_Load? For example this is part of the aspx page:
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:DataList ID="dlRecords" runat="server">
<FooterTemplate>
<asp:Panel ID="pnlArticleHeader" runat="server" Visible="false" >
</asp:Panel>
</FooterTemplate>
</asp:Datalist>
</asp:Content>
Here is something in the codebehind:
protected void Page_Load(object sender, EventArgs e)
{
location = Request.QueryString["location"];
if (location == "HERE")
{
Panel pnlAH = *Need to find control here*;
pnlAH.Visible=true;
}
}
Like I said I am new at this. Everything I have found doesn't seem to work so I decided to post a specific question. Thanks in advance
DataList has event OnItemCreated, overriding allows select type of row:
Panel _pnlArticleHeader;
void Item_Created(Object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
_pnlArticleHeader =(Panel)e.Item.FindControl("pnlArticleHeader");
}
}
After event invocation in the field: _pnlArticleHeader you will get desired panel. This way is safe since created only once. NOTE! same way for common DataList's row would return only last one.

Categories