Load user control dynamically on Button Click - asp.net

I have a label and a text box which i have added in the user control.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddMultiLoc.ascx.cs" Inherits="CRM_Streamline_Forms.UserControls.AddMultiLoc" %>
<table>
<tr>
<td style="width:25%">
<asp:Label ID="lblLocName_UC_G0138" runat="server" Text="Location Name:" />
</td>
<td style="width:25%">
<asp:TextBox ID="txtLocName_UC_G0138" runat="server" Width="200px" />
</td>
<td style="width:25%">
<asp:Label ID="lblLocID_UC_G0138" runat="server" Text="Location ID:" />
</td>
<td style="width:25%">
<asp:TextBox ID="txtLocID_UC_G0138" runat="server" Width="200px" />
</td>
</tr>
I have a link button in one of my aspx pages which is when clicked should populate this user control.
<asp:LinkButton ID="lnkAddLoc_AGBI2_G0138" runat="server" Text="+ Add Another Location" onclick="lnkAddLoc_AGBI2_G0138_Click" />
Code behind, I have written this code for the button click:
protected void lnkAddLoc_AGBI2_G0138_Click(object sender, EventArgs e)
{
AddMultiLoc con = (AddMultiLoc)LoadControl("~/UserControls/AddMultiLoc.ascx");
pnlMultiInvoiceInfo1_AGBI2_G0138.Controls.Add(con);
Panel p = new Panel();
Control uc = (Control)Page.LoadControl("~/UserControls/AddMultiLoc.ascx");
p.Controls.Add(uc);
p.Width = 200;
p.Height = 100;
pnlMultiInvoiceInfo1_AGBI2_G0138.Controls.Add(p);
}
First time the user control is populated as am calling it in the aspx page, but second time when i click on the link button, it is not populating the user control for the second time. Am new to coding, please help :(

The problem I think is that you are losing your controls across postback as the controls are loaded in to the ViewState.
Here is a sample where you can load the controls in to the Session which is not really good practice but it will work for your purposes:
AddMultiLocPage.aspx
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:LinkButton ID="lnkAddLoc_AGBI2_G0138" runat="server" Text="+ Add Another Location" OnClick="lnkAddLoc_AGBI2_G0138_Click" />
</div>
<asp:PlaceHolder runat="server" ID="Placeholder1"></asp:PlaceHolder>
</form>
</body>
</html>
AddMultiLocPage.aspx.cs
public partial class AddMultiLocPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoadControlsFromSession();
}
private List<AddMultiLoc> ViewStateControls
{
get { return (List<AddMultiLoc>) Session["ViewStateControls"]; }
set { Session["ViewStateControls"] = (List<AddMultiLoc>)value; }
}
private void LoadControlsFromSession()
{
if (ViewStateControls != null)
{
Placeholder1.Controls.Clear();
foreach (var c in ViewStateControls)
{
Placeholder1.Controls.Add(c);
}
}
}
protected void lnkAddLoc_AGBI2_G0138_Click(object sender, EventArgs e)
{
var con = (AddMultiLoc)LoadControl("~/AddMultiLoc.ascx");
con.ID = Guid.NewGuid().ToString();
List<AddMultiLoc> tmpList = ViewStateControls;
if(tmpList == null) tmpList = new List<AddMultiLoc>();
tmpList.Add(con);
ViewStateControls = tmpList;
LoadControlsFromSession();
}
}
UserControl Markup
<table>
<tr>
<td style="width: 25%">
<asp:Label ID="lblLocName_UC_G0138" runat="server" Text="Location Name:" />
</td>
<td style="width: 25%">
<asp:TextBox ID="txtLocName_UC_G0138" runat="server" Width="200px" />
</td>
<td style="width: 25%">
<asp:Label ID="lblLocID_UC_G0138" runat="server" Text="Location ID:" />
</td>
<td style="width: 25%">
<asp:TextBox ID="txtLocID_UC_G0138" runat="server" Width="200px" />
</td>
</tr>
</table>

No need to store control in session, Solution to your problem is :
ASPX Code :
< asp:LinkButton ID="lnkAddLoc_AGBI2_G0138" runat="server" Text="+ Add Another Location" onclick="lnkAddLoc_AGBI2_G0138_Click" />
<asp:Panel ID="Panel1" runat="server">
Code Behind :
protected void lnkAddLoc_AGBI2_G0138_Click(object sender, EventArgs e)
{
Control uc = (Control)Page.LoadControl("~/AddMultiLoc.ascx");
Panel1.Controls.Add(uc);
}
Any time you click on link button lnkAddLoc_AGBI2_G0138 it add new instance of User Control to Panel1.

Related

Required Field Validator not working on controls inside dynamically generated user control

I have a user control containing few server controls like text boxes and drop down lists.
i have also added few required field validation controls. Normally these validation work fine, if I add the user control in design time.
But when I add the user control dynamically, the validation control just don’t work and page is posted back.
User Control:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="myUserControl.ascx.cs" Inherits="myUserControl" %>
<table cellpadding="0" cellspacing="0" >
<tr>
<td>
<asp:TextBox runat="server" ID="txtLastName" Width="80px" MaxLength="64" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="txtLastName" runat="server" ErrorMessage="Required Value" Display="None"></asp:RequiredFieldValidator>
<ajaxToolkit:ValidatorCalloutExtender ID="ValidatorCalloutExtender1" runat="server" TargetControlID="RequiredFieldValidator1"></ajaxToolkit:ValidatorCalloutExtender>
</td>
<td>
<asp:TextBox runat="server" ID="txtFirstName" Width="80px" MaxLength="64" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" ControlToValidate="txtFirstName" runat="server" ErrorMessage="Required Value" Display="None"></asp:RequiredFieldValidator>
<ajaxToolkit:ValidatorCalloutExtender ID="ValidatorCalloutExtender2" runat="server" TargetControlID="RequiredFieldValidator2"></ajaxToolkit:ValidatorCalloutExtender>
</td>
<td>
<asp:Button ID="btnDelete" runat="server" Text="Delete" OnClick="DeleteButton_Click" CausesValidation="false" />
</td>
</tr>
</table>
Containing Form Markup:
<form id="form1" runat="server">
<div>
<div align="right" ><asp:Button ID="btnAdd" runat="server" Text="Add Order Line" onclick="btnAdd_Click" CausesValidation="false" /></div>
<asp:PlaceHolder runat="server" ID="DynamicNameList" />
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" />
</div>
</form>
Containing Form Code:
public partial class WebForm1 : System.Web.UI.Page, IDynamicControlContainer
{
protected void Page_Load(object sender, EventArgs e)
{
foreach (string id in LoadControlIdList())
{
Create(id);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
}
protected void btnAdd_Click(object sender, EventArgs e)
{
Create(null);
}
public void Create(string id)
{
string targetId = id ?? Guid.NewGuid().ToString();
myUserControl control = LoadControl("~/CustomControls/myUserControl.ascx") as myUserControl;
control.ID = targetId;
DynamicNameList.Controls.Add(control);
SaveControlIdList();
}
public void Delete(Control control)
{
DynamicNameList.Controls.Remove(control);
SaveControlIdList();
}
public void SaveControlIdList()
{
List<string> idList = new List<string>();
foreach (Control control in DynamicNameList.Controls)
{
idList.Add(control.ID);
}
ViewState["IdList"] = idList;
}
public string[] LoadControlIdList()
{
var list = (List<string>)ViewState["IdList"];
if (list == null)
{
return new string[0];
}
return list.ToArray();
}
}
public interface IDynamicControlContainer
{
/// <summary>
/// Deletes the specified control from the container
/// </summary>
/// <param name="control">The control.</param>
void Delete(Control control);
}
}
You need to use either the Page_Init or CreateChildControls events to do this. By the time Page_Load kicks in, the control tree is already loaded.

ASP.NET Form Default Button is not working.

ASP.NET Default button and default focus is not working. My application is hosted on IIS in my server manchine. (Servername say Server1). If i am accessing the application URL outside of machine focus and default button click is working fine (http://Server1/VPath/Login.aspx) . If i am accessing the application URL using localhost in the server it is working fine (http://localhost/VPath/Login.aspx) but focus and default button click (on Enter) is not working when i am accessing the URL using server name in the server. (http://server1/VPath/Login.aspx). What could be the issue?
Note: IE version is same in all the above cases.
Here are my code files.
Login.aspx
<asp:Panel ID="LoginWrapper" runat="server" CssClass="loginWrapper" >
<asp:Login ID="LoginControl" runat="server" meta:resourcekey="LoginResource1"
DisplayRememberMe="false" OnAuthenticate="authenticate">
<LayoutTemplate>
<table>
<tr>
<td>
<asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName" meta:resourcekey="UserNameLabelResource1"
Text="User Name:"></asp:Label></td>
<td>
<asp:TextBox ID="UserName" runat="server" meta:resourcekey="UserNameResource1"></asp:TextBox>
<asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName"
ErrorMessage="User Name is required." ToolTip="User Name is required."
meta:resourcekey="UserNameRequiredResource1" Text="*"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
<asp:Label ID="PasswordLabel" runat="server" AssociatedControlID="Password" meta:resourcekey="PasswordLabelResource1"
Text="Password:"></asp:Label></td>
<td>
<asp:TextBox ID="Password" runat="server" TextMode="Password" meta:resourcekey="PasswordResource1"></asp:TextBox>
</td>
</tr>
<tr>
<td colspan="2" style="text-align: center; color: red">
<asp:Literal ID="FailureText" runat="server" EnableViewState="False" meta:resourcekey="FailureTextResource1"></asp:Literal>
</td>
</tr>
<tr>
<td>
</td>
<td>
<asp:Button ID="LoginButton" runat="server" CommandName="Login" Text="Login"
meta:resourcekey="LoginButtonResource1" /></td>
</tr>
</table>
</LayoutTemplate>
</asp:Login>
</asp:Panel>
Login.aspx.cs
protected void Page_Init(object sender, EventArgs e)
{
Response.RedirectLocation = Request.Url.ToString();
// bug#19156 Enter key should Login
LoginControl.Focus();
Page.Form.DefaultButton = ((Button)LoginControl.FindControl("LoginButton")).UniqueID;
}
protected void Page_Load(object sender, EventArgs e)
{
log.Debug("Loading login Page");
try
{
if (Request.QueryString["activity"] != null)
{
string activity = Request.QueryString["activity"].ToString();
switch (activity)
{
case "login":
if (Request.QueryString["Username"] != null)
un = Request.QueryString["Username"].ToString();
if (Request.QueryString["Password"] != null)
pw = Request.QueryString["Password"].ToString();
authenticate(null, null);
break;
}
}
}
catch (ExecutionEngineException ex)
{
}
if (Request.IsAuthenticated && !IsPostBack)
{
Response.Redirect("~/VPath/NotAuthorized.aspx");
}
else if (!IsPostBack)
{
HideTopMenu();
}
}
I do not know why your code is not working when accessed from outside but i think the problem
is with page_init event .
so better i would suggest to override it and this is safe too:-
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Response.RedirectLocation = Request.Url.ToString();
// bug#19156 Enter key should Login
LoginControl.Focus();
Page.Form.DefaultButton = ((Button)LoginControl.FindControl("LoginButton")).UniqueID;
}

Server controls null in Page_Load

I have a page that has some server controls in it. For some reason these controls are null in the page's Page_Load event handler.
<asp:Content ID="mainContent" runat="server" ContentPlaceHolderID="mainPlaceholder">
<asp:Label ID="userIdLockedLabel" runat="server" EnableViewState="False" ForeColor="Red"
Visible="False">
</asp:Label>
<asp:Panel ID="standardLoginPanel" runat="server">
<asp:Login ID="loginControl" runat="server"
DisplayRememberMe="false"
PasswordRecoveryUrl="?action=lostpass"
TextBoxStyle-Font-Names="verdana"
TextBoxStyle-Font-Size="Small"
DestinationPageUrl="Home.aspx"
OnLoggingIn="OnLoggingIn"
OnLoginError="OnError"
TitleText="" >
<TextBoxStyle Font-Names="verdana" Font-Size="Small"></TextBoxStyle>
<LoginButtonStyle CssClass="btn" />
</asp:Login>
</asp:Panel>
<asp:Panel ID="canadaLoginPanel" runat="server" Visible="false">
<asp:Label ID="userFailureLabel" runat="server"></asp:Label>
<table>
<tr>
<td><%= Utility.RetrieveResource("CompanyNumberLabel") %></td>
<td><asp:TextBox ID="companyNumberTextbox" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><%= Utility.RetrieveResource("UserIdLabel")%></td>
<td><asp:TextBox ID="userIdTextbox" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td><%= Utility.RetrieveResource("PasswordLabel")%></td>
<td><asp:TextBox ID="userPasswordTextbox" runat="server" TextMode="Password"></asp:TextBox></td>
</tr>
<tr>
<td colspan="2">
<asp:CheckBox ID="rememberMeCheckBox" runat="server" />
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><asp:Button ID="userSubmit" runat="server" CssClass="btn" /></td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><%= Utility.RetrieveResource("ForgotPasswordLinkText") %></td>
</tr>
</table>
</asp:Panel>
<br />
<div style="font-family: Verdana; font-size: small">
<span class="bold">
<%= Utility.RetrieveResource("TroubleLogginIn") %>
</span><br />
<%= Utility.RetrieveResource("ForgotPasswordText") %>
</div>
The page, login.aspx inherits from LogOnBasePage, and that is where the Page_Load code is. In there, I use the following code:
if (this.Company.SiteType == Ceridian.KB.Entities.SiteType.CAN)
{
this.FindControlRecursive("standardLoginPanel").Visible = false;
this.FindControlRecursive("canadaLoginPanel").Visible = true;
((Button)this.FindControlRecursive("userSubmit")).Text = Utility.RetrieveResource("LoginButtonText");
this.Login = null;
CheckBox rememberMe = (CheckBox)this.FindControlRecursive("rememberMeCheckBox");
rememberMe.Text = Utility.RetrieveResource("RememberMeText");
}
Here is the content of the FindControlRecursive method.
public static Control FindControlRecursive(this Control control, string controlId)
{
if (string.Compare(control.ID, controlId, StringComparison.OrdinalIgnoreCase) == 0)
{
// We found the control!
return control;
}
else
{
// Recurse through ctrl's Controls collections
foreach (Control child in control.Controls)
{
Control lookFor = FindControlRecursive(child, controlId);
if (lookFor != null)
{
// We found the control
return lookFor;
}
}
// If we reach here, control was not found
return null;
}
}
I always get a null reference on the first line inside the if check. I don't see how this is possible.
It might be that you need to wait later in the page lifecycle. try putting it in the page_prerendercomplete event like this
Page_PreRenderComplete(Object sender, EventArgs e)
{
if (this.Company.SiteType == Ceridian.KB.Entities.SiteType.CAN)
{
this.FindControlRecursive("standardLoginPanel").Visible = false;
this.FindControlRecursive("canadaLoginPanel").Visible = true;
((Button)this.FindControlRecursive("userSubmit")).Text = Utility.RetrieveResource("LoginButtonText");
this.Login = null;
CheckBox rememberMe = (CheckBox)this.FindControlRecursive("rememberMeCheckBox");
rememberMe.Text = Utility.RetrieveResource("RememberMeText");
}
Does the page you are inheriting from use a markup file (e.g. LogOnBasePage.aspx)?
If so then I think you are out of luck inheriting from it. The markup page generates a class that inherits from the class defined in the code behind page. One of the responsibilities of this generated class is to instantiate the controls defined in the markup. If you inherit from LogOnBasePage your new page will not have the code necessary to instantiate the controls from LogOnBasePage markup and therefore you will get null references.

Confirmation box from server side in asp.net

I want to show the confirmation box in asp.net from server side:
I want to call it from server side because I have to take the customer message from server side. I am using the below code
string str = "Are you sure, you want to Approve this Record?";
ClientScript.RegisterStartupScript(typeof(Page), "Popup", "return confirm('" + str + "');",true);
// More code ....
Now it is showing the popup and irrespective of what I click, whether "ok" or "Cancel", my code is executing.
Please let me know how can I restrict code to be executed when user select "cancel" in the confirmation box.
Check it out:
CODE BEHIND:
string str = "Are you sure, you want to Approve this Record?";
this.ClientScript.RegisterStartupScript(typeof(Page), "Popup", "ConfirmApproval('" + str + "');", true);
ASPX:
function ConfirmApproval(objMsg)
{
if(confirm(objMsg))
{
alert("execute code.");
return true;
}
else
return false;
}
check following example code.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Button ID="btnOK" runat="server" Text="OK" onclick="btnOK_Click" />
<cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server" TargetControlID="lblID" PopupControlID="pnlConfirmation">
</cc1:ModalPopupExtender>
<asp:Panel ID="pnlConfirmation" runat="server" Style="background-color: #D4D0C8;
border: 2px solid black; width: 300px; height: 100px;">
<asp:Label ID="lblID" runat="server"></asp:Label>
<table cellpadding="2" cellspacing="2" width="100%">
<tr>
<td>
Your confirmation message here.
</td>
</tr>
<tr>
<td align="center">
<asp:Button ID="btnOK1" runat="server" Text="OK" onclick="btnOK1_Click" /> <asp:Button ID="btncancel"
runat="server" Text="Cancel" onclick="btncancel_Click" />
</td>
</tr>
</table>
</asp:Panel>
On server side.....
protected void btnOK_Click(object sender, EventArgs e)
{
//some code here.
//then show modal popup
ModalPopupExtender1.Show();
}
protected void btnOK1_Click(object sender, EventArgs e)
{
//If ok some code here to execute
ModalPopupExtender1.Hide();
}
protected void btncancel_Click(object sender, EventArgs e)
{
//hide modal popup
ModalPopupExtender1.Hide();
}
http://forums.asp.net/t/1499789.aspx?confirmation+popup+from+server+side

ListView fields not getting posted

I know I've done something like this before, but I have no idea why it isn't working now. I have a ListView with some textboxes. I want to read the text out of those boxes when I click a button (linkbutton, whatever).
<asp:ListView runat="server" ID="lv_bar" EnableViewState="true">
<LayoutTemplate>
<table>
<tr>
<th>Foo</th>
</tr>
<tr runat="server" id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton ID="lb_delete" CausesValidation="false" runat="server" Text="Del" /></td>
<td><asp:TextBox id="txt_foo" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:LinkButton ID="lb_add" CausesValidation="false" runat="server" Text="Add" />
And then here's the relevant code-behind stuff:
protected void Page_Load(object sender, EventArgs e)
{
lb_chapter_add.Click += lb_chapter_add_Click;
if (!IsPostBack)
{
lv_chapters.DataSource = new List<Foo>() { new Foo() { Name = "harbl"} };
lv_chapters.DataBind();
}
}
void lb_add_Click(object sender, EventArgs e)
{
foreach (ListViewDataItem item in lv_bar.Items)
{
var txt_foo = (TextBox)item.FindControl("txt_foo");
Response.Write("foo: " + txt_foo.Text);
}
Response.Write("<br />the end");
Response.End();
}
But what I see when I enter some text into txt_foo and click lb_add is just "the end". What am I doing wrong here?
The problem it that you are using a a non persistent object as DataSource.
Due to clicking the button, you generate a postback and lv_chapters does not contain any items. Set a breakpoint in the line where the foreach is and you will see that lv_chapters.Items in null, or that it's Count property returns 0.

Resources