I have a simple web page which has a UserControl(.ascx). Here is my UserControl source
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ucReportTextBox.ascx.cs"
Inherits="Intranet.UserControl.ucReport" %>
<table width="100%">
<tr>
<td>
<asp:TextBox ID="txtQuery" runat="server" Width="250px" />
</td>
</tr>
</table>
And my web page source
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage/DefaultMasterPage.Master"
AutoEventWireup="true" CodeBehind="ComposeReport.aspx.cs" Inherits="Intranet.MasterPage.WebForm4" %>
<%# Register Src="~/UserControl/UcReportTextBox.ascx" TagName="UcReportTextBox" TagPrefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="contentHead" runat="server"/>
<asp:Content ID="Content2" ContentPlaceHolderID="contentBody" runat="server">
<table>
<tr>
<td>
<uc1:UcReportTextBox ID="ucReporttxt" runat="server" />
</td>
</tr>
//includes so many tags
</table>
</asp:Content>
In code behind of my web page
protected void Page_Load(object sender, EventArgs e)
{
InitComponent();
}
private void InitComponent()
{
XDocument document = XDocument.Load("ReportXML.xml");
var parameterTypes = document.Descendants("Type");
foreach (var parType in parameterTypes)
{
if (parType.Value == "string") //TODO Enumerate it !!
{
ucReporttxt.addTextBox();
}
}
}
In code behind of usercontrol
public void addTextBox()
{
TextBox txtBox = new TextBox();
txtBox.ID = "txtBox";
txtBox.Width = 170;
Page.Form.Controls.Add(txtBox);
}
As you understand I'm newer to asp.net , in PageLoad I'm reading XMLfile to whether or not add textbox to page. The codes add textboxes correctly but the textboxes are added at the end of the page. I want to add textbox at the part of ucReportText not the end of the page how can fix it ?
Thanks for your help.
You can add an asp panel to the user control and add the textbox to the panel controls and not the page controls. Then just place the panel where ever you want the textboxes to appear.
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage/DefaultMasterPage.Master"
AutoEventWireup="true" CodeBehind="ComposeReport.aspx.cs" Inherits="Intranet.MasterPage.WebForm4" %>
<%# Register Src="~/UserControl/UcReportTextBox.ascx" TagName="UcReportTextBox" TagPrefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="contentHead" runat="server"/>
<asp:Content ID="Content2" ContentPlaceHolderID="contentBody" runat="server">
<table>
<tr>
<td>
<uc1:UcReportTextBox ID="ucReporttxt" runat="server" />
<asp:panel runat="server" id="pnlContainer"></asp:panel>
</td>
</tr>
//includes so many tags
</table>
</asp:Content>
public void addTextBox()
{
TextBox txtBox = new TextBox();
txtBox.ID = "txtBox";
txtBox.Width = 170;
pnlContainer.Controls.Add(txtBox);
}
In order to control where you dynamically add elements from your code-behind, add a PlaceHolder control to the page and append them there. Something like this:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ucReportTextBox.ascx.cs" Inherits="Intranet.UserControl.ucReport" %>
<table width="100%">
<tr>
<td>
<asp:TextBox ID="txtQuery" runat="server" Width="250px" />
<asp:PlaceHolder runat="server" ID="phAdditionalTextBoxes" />
</td>
</tr>
</table>
(Note: It's not entirely clear where you want your dynamic text boxes added, so move the PlaceHolder accordingly.)
And in the code:
TextBox txtBox = new TextBox();
txtBox.ID = "txtBox";
txtBox.Width = 170;
phAdditionalTextBoxes.Controls.Add(txtBox);
The textboxes are being added to the end of the page because that's where Page.Form.Controls.Add(txtBox); puts them, yiou are adding textboxes to the end of the Page holding your UC,
Add a Placeholder control to your UC, then add the new textboxes to the placeholder.
Related
In classic ASP i could do this when looping throu a unknown inputfields:
<input id="textbox1" type="text">
<input id="textbox2" type="text">
<input id="textbox3" type="text">
<input id="textbox4" type="text">
<input id="textbox5" type="text">
For i = 1 To 5
strTextbox = request.form("textbox" & i)
If strTextbox <> "" Then
// Do the magic!
End If
Next
With this the user could input values to textbox 1, 3, 4 and 5 or maybe only 1 and 2 and i could collect the values inputs in the For loop.
How could i do this in C#?
I cant do this because it dosent like that i add a i in the middle om my textbox.Text;
for (int i = 1; i < 6; i++)
{
strTextbox = textbox[i].Text;
if (!string.IsNullOrEmpty(strTextbox)
{
// Do the magic!
}
}
I now have a lot of if:s checking every textbox inside the loop but it got to be a easyer way?
You can use FindControl on the NamingContainer of your textboxes.
If they're are on top of the page and not nested in other controls like GridView:
for (int i = 1; i < 6; i++)
{
string strTextbox = "textbox" + i.ToString();
TextBox txt = this.FindControl(strTextbox) as TextBox;
if (txt != null && !string.IsNullOrEmpty(txt.Text))
{
// ...
}
}
But i would use more meaningful names instead.
I want access to the textboxes from a button_click event only on the
actual page. The controls are inside a panel.
Then i would use this LINQ approach:
List<TextBox> filledArticleTBS = txtPanel.Controls.OfType<TextBox>()
.Where(txt => txt.ID.StartsWith("textbox") && !String.IsNullOrEmpty(txt.Text))
.ToList();
I did manage to get this working with some extra lines.
So the final code was to first find Contentplaceholder in my top master, then search for the Contentplaceholder in my nested Masterpage and finaly search for the textbox. It works, but when debugging i can see that there are some other isues with the code where in some cases the textbox is'nt found. I'm going back to my previusly working code where i access all the controls directly and not with findcontrol. But if someone is intrested this worked (almost) for me:
My Top Masterpage (Site.Master)
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="mysite.SiteMaster" %>
<html>
<head>
// MasterPage head stuff
// ...
</head>
<body>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
// My contentpages that use only the top masterpage
// My contentpage contacts.aspx begin here, This is in a separate file called contacts.aspx.
// In code the contentpage is theoretically here, when the site runns it works in another way. Here things are explained; http://odetocode.com/articles/450.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="contacts.aspx.cs" Inherits="mysite.contacts" %>
<asp:Content ID="contactsContent" ContentPlaceHolderID="MainContent" runat="server">
// Here is the content of a contentpage (contacts.aspx) that use the Site.Master
</asp:Content>
// contentpage contacts.aspx end here
</asp:ContentPlaceHolder>
</body>
</html>
My Nested Masterpage (XYZ.master)
<%# Master Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="XYZMasterPage.master.cs" Inherits="mysite.XYZ.XYZMasterPage" %>
<asp:Content ID="NestedMasterPageContentPlaceHolder" ContentPlaceHolderID="MainContent" runat="server">
Nested MasterPage stuff
...
<asp:ContentPlaceHolder ID="NestedMainContent" runat="server">
// Here is my contentpage where textbox1, 2, 3 etc. is
// Here is the content of a contentpage (batch.aspx) that use the nested masterpage XYZMasterPage.master
<%# Page Title="" Language="C#" MasterPageFile="~/XYZMasterPage.master" AutoEventWireup="true" CodeBehind="batch.aspx.cs" Inherits="mysite.XYZ.batch" %>
<asp:Content ID="batchInvContent" ContentPlaceHolderID="NestedMainContent" runat="server">
// Here is the content of a contentpage (batch.aspx)
<asp:Panel ID="PanelBatch" Runat="Server" >
<asp:TextBox runat="server" ID="ArticleNr1" />
<asp:TextBox runat="server" ID="ArticleNr2" />
<asp:TextBox runat="server" ID="ArticleNr3" />
<asp:TextBox runat="server" ID="ArticleNr4" />
<asp:TextBox runat="server" ID="ArticleNr5" />
<asp:Button runat="server" ID="buttSubmit" OnClick="buttSubmit_Click" />
</asp:Panel>
</asp:Content>
// contentpage batch.aspx end here
</asp:ContentPlaceHolder>
My codebehindfile for batch.aspx
protected void buttSubmit_Click(object sender, EventArgs e)
{
ContentPlaceHolder parentCP = this.Master.Master.FindControl("MainContent") as ContentPlaceHolder;
ContentPlaceHolder childCP = parentCP.FindControl("NestedMainContent") as ContentPlaceHolder;
string strTextbox = string.Empty;
for (int i = 1; i < 6; i++)
{
strTextbox = "ArticleNr" + i.ToString();
TextBox txt = childCP.FindControl(strTextbox) as TextBox;
if (txt != null && !string.IsNullOrEmpty(txt.Text))
{
// ...
// Insert to db
// ...
}
}
}
As posted earlier , Here is my HTML :
<%# Page Title="" Language="C#" MasterPageFile="~/VendorMaster.master" AutoEventWireup="true" CodeFile="PastOrders.aspx.cs" Inherits="PastOrders" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<br />
<asp:Repeater ID="rptr" runat="server">
<HeaderTemplate>
<div class="col-lg-4 col-md-4 col-sm-4 mb">
<a href="VendorProfile.aspx">
<div class="twitter-panel pn">
<i class="fa fa-twitter fa-4x"></i>
</HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Name") %>
</ItemTemplate>
<FooterTemplate>
</div>
</a>
</FooterTemplate>
</asp:Repeater>
</asp:Content>
C# :
public partial class PastOrders : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session["vendor"] != null)
{
if (!IsPostBack)
{
ArrayList values = new ArrayList();
values.Add(new Testing
{
Name = "Caterer"
});
values.Add(new Testing
{
Name = "Florist"
});
values.Add(new Testing
{
Name = "Cab Services"
});
rptr.DataSource = values;
rptr.DataBind();
}
}
else
{
Response.Redirect("VendorLogin.aspx");
}
}
public class Testing
{
public string Name { get; set; }
}
}
Now i want to generate 3 separate divs, with the Names on them as : "Caterer","Florist","Cab Services",etc.
Instead it is only generating one div with all the 3 names inside it .
I tried formatting it with the Header Template and the Footer Template where i put the parent divs and the anchor tag in the Header Template and the closing of the same in the Footer Template . Bt it doesn't produce the expected result still.
Now you do bind data, but you do not access your data within your repater. Change it to
<form id="form1" runat="server">
<asp:Repeater ID="rptr" runat="server" >
<ItemTemplate>
<div class="divStyle" id="divStyle">
<%# DataBinder.Eval(Container.DataItem, "Name") %>
</div>
</ItemTemplate>
</asp:Repeater>
</form>
and it should work!
I am trying to create a page using Ajax Tabs and user controls. The .aspx page contains a reference to a default control
<%# Register src="~/Controls/DefaultControl.ascx" tagname="DefaultControl" tagprefix="uc1" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<uc1:DefaultControl ID="DefaultControl1" runat="server" />
<%--<uc2:CorrespondenceControl ID="CorrespondenceControl" runat="server" />--%>
</asp:Content>
And the DefaultControl.ascx is using Ajax Tabs, one of which contains a child control within an Update Panel
asp:TabPanel ID="tbpnl2" runat="server" HeaderText="Tab With GridView with select buttons" Visible="True">
<ContentTemplate>
<asp:UpdatePanel ID="updpnl2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<uc2:Control1 ID="Control1" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</asp:TabPanel>
The DefaultControl holds a method in the code behind page which is successfully called directly from other tabs (with the markup contained directly in DefaultControl.ascx) on the DefaultControl.ascx page to change the display when Select is clicked on a gridview -
public void ShowPage()
{
gv1.DataBind();
fv1.DataBind();
tbpnl1.Visible = true; //show details tab
tbpnl2.Visible = true;
tab1.ActiveTabIndex = 1; //set details tab as current tab
txt.Text = String.Empty;
updPnl1.Update();
}
I am trying to call this method from the child Control1 when Select on a gridview is selected there, but obviously none of the elements referenced are in Control1.
I have been searching for a way to be able to use the existing method and have seen a number of suggestions including Interfaces, references like ((DefaultControl)this.DefaultControl).ShowPage(); on the code behind Control1
But as I am just starting to program I have no idea how to implement any of these solutions or what the syntax should be to get them to work.
Is there a simple, even if dirty, way to use the method from a parent control in a child control contained in an Ajax tab?
Not sure if this is what you are looking for... Below example shows calling of direct UserControl and nested UserControl method's from Web page
Default.aspx
<%# Register TagPrefix="uc" TagName="WebUserControl" Src="WebUserControl.ascx" %>
<%# Register TagPrefix="uc2" TagName="WebUserControl2" Src="WebUserControl2.ascx" %>
<form runat="server" id="form1">
<uc:WebUserControl ID="control1" runat="server" />
<hr />
<h4>
At Default.aspx</h4>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Call the function" />
</form>
Default.aspx.cs
protected void Button1_Click(object sender, EventArgs e)
{
control1.CallMe();
var control2 = (WebUserControl2)control1.FindControl("control2");
control2.CallMe2();
}
WebUserControl.ascx
<%# Register TagPrefix="uc2" TagName="WebUserControl2" Src="WebUserControl2.ascx" %>
<div runat="server">
<h3>
WebUserControl</h3>
<asp:Label ID="lbl1" Text="I am ready at WebUserControl" runat="server"></asp:Label>
<div runat="server" id="toAdd" style="color: Red;">
</div>
</div>
<hr />
<uc2:WebUserControl2 ID="control2" runat="server" />
WebUserControl.ascx.cs
public void CallMe()
{
Label lbl = new Label();
lbl.Text = "I am at WebUserControl";
toAdd.Controls.Add(lbl);
}
WebUserControl2.ascx
<div runat="server">
<h3>
WebUserControl2</h3>
<asp:Label ID="lbl1" Text="I am ready at WebUserControl2" runat="server"></asp:Label>
<div runat="server" id="toAdd" style="color: Red;">
</div>
</div>
WebUserControl2.ascx.cs
public void CallMe2()
{
Label lbl = new Label();
lbl.Text = "I am at WebUserControl2";
toAdd.Controls.Add(lbl);
}
Hope it helps someone...!!
I have a master page master.page.
And I have a child page default.aspx that inheirts master.
How do I preform the following and actually find controls. In the below code I never find my panels.
codebehind - content-page
foreach (Panel pnl in this.Page.Controls.OfType<Panel>())
{
if (pnl.ID.ToUpper() == texthi.ToUpper().Replace(" ", ""))
{
pnl.Visible = true;
}
else
{
pnl.Visible = false;
}
}
aspx - content-page
<%# Page Title="" Language="C#" MasterPageFile="~/secure/Wizard.master" AutoEventWireup="true"
CodeFile="AddWarranty.aspx.cs" Inherits="secure_Warranties_AddWarranty" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder_NavigationPanel"
runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:ScriptManager runat="server" ID="sm1">
</asp:ScriptManager>
<div id="header">
<p id="layoutdims">
</p>
</div>
<div class="colmask leftmenu">
<div class="colleft">
<div class="col1">
<asp:Panel runat="server" ID="VehicleInformation" Visible="true">
<legend>VEHICLE INFORMATION</legend>
</asp:Panel>
<asp:Panel runat="server" ID="CustomerInformation" Visible="false">
<legend>CUSTOMER INFORMATION</legend>
</asp:Panel>
</div>
The reason is that Enumerable.TypeOf does not look recursivelsy into child controls but only the top-container. Since you're using it on the page's ControlCollection you'll find only panels which are sitting on the top of the page. But your panels are inside of other divs.
Make the parent div(with class="col1") runat=server(or use Panel) and access it in codebehind:
foreach (Panel pnl in div.Controls.OfType<Panel>())
{
// ...
}
For some reason, I cannot get text into any textbox or label!
I'm using Master pages and the code is going in the code behind view. I have created the textbox:
<asp:Textbox ID="whatever" runat="Server">
When I want to add some text I simply add the code in the code behind view like:
whatever.Text = "myText";
I get an error that says:
"System.NullReferenceException:Object reference not set to an instance of an object"
hightlighting this line in red: whatever.Text = "myText";
I guess its because it saying it not there but how can it let me reference the textbox?
Apologies if the answer is on the site, I have searched but found nothing. :)
This is my code in Basket.asp - I've changed the textbox to a label, it's called bskItems
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder3" runat="server">
<asp:Label ID="bskItems" runat="server"></asp:Label>
<div id="cart">
<asp:Button ID="btnCheckout" CssClass="BasketBtnAdd" runat="server" CommandName="checkout" Text="Checkout" />
</div>
</asp:Content>
This is my masterpage, where I'm using a loginView. ContentPlaceHolder3 is where the textbox should be. I only want it to display a count of items.
<asp:LoginView ID="loginView" runat="server">
<LoggedInTemplate>
<asp:LoginName ID="loginName" runat="server" FormatString="Hi, {0}!"/>
(<asp:LoginStatus ID="loginStatus" runat="server" />)
<%
if (HttpContext.Current.User.IsInRole("Admin"))
{
%>
<asp:SiteMapDataSource ID="admin" SiteMapProvider="admin" runat="server" ShowStartingNode="false" />
<asp:Menu ID="Menu" runat="server" DataSourceID="admin">
<StaticItemTemplate>
<%# Eval("Text") %>
</StaticItemTemplate>
</asp:Menu>
<%
}
if (HttpContext.Current.User.IsInRole("Users"))
{
%>
<asp:SiteMapDataSource ID="user" runat="server" SiteMapProvider="user" ShowStartingNode="false" />
<asp:Menu ID="Menu1" runat="server" DataSourceID="user">
<StaticItemTemplate>
<%# Eval("Text") %>
</StaticItemTemplate>
</asp:Menu>
<%
}
%>
<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server"></asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="ContentPlaceHolder3" runat="server"></asp:ContentPlaceHolder>
</LoggedInTemplate>
<AnonymousTemplate>
<asp:LoginStatus ID="loginStatus" runat="server" />
<asp:SiteMapDataSource ID="anon" runat="server" SiteMapProvider="anon" ShowStartingNode="false" />
<asp:Menu ID="Menu2" runat="server" DataSourceID="anon">
<StaticItemTemplate>
<%# Eval("Text") %>
</StaticItemTemplate>
</asp:Menu>
</AnonymousTemplate>
</asp:LoginView>
In addition to the other answers, if you're setting the value in Page.OnLoad, remember that the Master page controls haven't been created yet.
Here's a complete layout of the order in which things happen: Complete Lifecycle of an ASP Page
What I usualy do is to make the control visible as a property of my MasterPage.
On the master page (AMasterPage.master):
public TextBox MyTextBox { get { return this.theTextBoxControl; } }
So then, on a child using this masterPage (APage.aspx) :
((AMasterPage)this.Master).MyTextBox.Text = "myText";
When accessing Master Page members from Code-Behind in a Content Place Holder file, I believe you need to do:
this.Master.whatever.Text = "new Text";
Check this link on ASP.NET Master Pages, from MSDN.
You need to do get a reference to the textbox on the master page, then set the text
TextBox tb = Master.Page.FindControl("whatever") as TextBox;
if(tb != null)
{
tb.Text = "myText";
}
Set the ClientIDMode on the textbox to "Static". When the page is rendered it assigns the TextBox's ID to something random. By changing the ClientIDMode to "Static", you should be able to reference the ID because the ID will stay the same and not change.
Or try adding an OnDataBinding event handler and casting the "sender" as a (TextBox). For example:
protected void TextBox_OnDataBinding(object sender, EventArgs e)
{
var txt = (TextBox)sender;
txt.Text = "Something";
}
This should talk to the control directly.