I'm trying to figure out how to find a "div" which is in my main .aspx page from a class, is this possible? If so how? I've tried the code below but is not working
HtmlGenericControl step1 = (HtmlGenericControl)Page.FindControl("step1")
I know this is the way I would do it in the code behind file but in this case I want to do it from a class file.
Thank you in advance.
Basically what I'm trying to accomplish is this, I have multiple divs in my page all of the have runtat="server" visible="false" when certain criteria is met I want to be able to change the visible="true". I have this scenario in multiple pages so I want to be able to create a Class and check for the conditions there and through this way make the div visible or un-visible
The div element must have the runat="server" attribute:
<body>
<form id="form1" runat="server">
<div id="step1" runat="server"></div>
</form>
</body>
Now, you can find the control with a method in a separated class, which is called from the code behind class of the page:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Class1 class1 = new Class1();
class1.FindDiv(this);
}
}
Separated class:
public class Class1
{
public HtmlGenericControl FindDiv(Page page)
{
HtmlGenericControl step1 = (HtmlGenericControl)page.FindControl("step1");
return step1;
}
}
If you use ASP Panel instead of a div u can access it and Panel renders as div. If u give runat="server" to a div u should be able to access it.
You cannot do that if it is not a server side control..
If it is a HTML control you need to set runat="server" attribute to the div to find it in code behind..
Try
HtmlGenericControl div = (HtmlGenericControl)this.FindControl("div1");
Note : In order to make this code work, you need to have runat="server" property at aspx page.
Related
I have 2 files, Test.aspx and MyControl.ascx.
In Test.aspx's html:
<MyControl>
<MyTemplate>
<div>sample text, other controls</div>
</MyTemplate>
</MyControl>
In MyControl.ascx.cs:
[ParseChildren(ChildrenAsProperties=true)]
[PersistChildren(true)]
public class MyControl:Control
{
[Browsable(true)]
public ITemplate MyTemplate{ get; set; }
protected override void OnLoad(EventArgs e)
{
//get the template html, but how to get???
var templateHtml = this.MyTemplate.ToString();
}
}
I want to get the content of the <MyTemplate> tag (<div>sample text, other controls</div>) from codebehind within MyControl.ascx.cs.
Who can help me? Thanks.
You would need to make the div a server side control as so:
<MyControl>
<MyTemplate>
<div runat="server" id="divContent">sample text, other controls</div>
</MyTemplate>
Now, in your code behind, depending on what kind of control is this and how is that div rendered, you should be able to do something like this:
var innerHtml = yourControl.FindControl("divContent").InnerHtml;
Again, this depends on how is the div rendered. If it's inside a row (assuming your control is a list of some kind), then you would need to get a reference to the row and then call FindControl("divContent") on the row.
I have a web page and it contains an user control inside of it. I have a property on the aspx page which gets set in the pageinit method and I need to that propery on ascx page.
How can I get it?
Create a public property inside the ascx and set it at the same time you set in the aspx page.
Just to let you know, PreInit is a EventHandler not a method.
MyAdminPage myPageInstance = this.Parent as MyAdminPage;
if(myPageInstance != null)
{
...
}
There has been a few questions on this.
Reference .aspx property from .ascx
The easiest options are as follows:
Use a public variable and access it from the parent page.
Assign the variable to a hidden field on the ascx front end. A field like this: <asp:HiddenField ID="ascxField" runat="server" /> .
The example below is for #1, but #2 is almost the same.
Example #1:
Aspx page:
Front end:
<%# Register TagPrefix="Admin" TagName="MyUserControl" Src="~/UserControls/.../MyUserControl" %>
...
<Admin:MyUserControl ID="MyUserControl" AutoPostBack="true" runat="server" Visible ="false" />
Code Behind:
this.MyUserControl.Variable1 = 1;
this.MyUserControl.Variable2= "value";
Ascx page:
Code Behind
public int Variable1 { get; set; }
public string Variable2 { get; set; }
I have a master page which has a content section with the id cpMainContent.
I am using this master page on every webform I am creating for college project. One of such form is frmSearchPersonnel. The purpose of frmSearchPersonnel is to ask user last name of the person they want to search in a textbox and then click on search button. The ID of TextBox is
txtSearchName
Search button will do postbackUrl transfer to another form which I have named frmViewPersonnel.
In frmViewPersonnel I am trying to use following code.
NameValueCollection myRequest = Request.Form;
if(!string.IsEmptyOrNull(myRequest["txtSearchName"]))
string strSearch = myRequest["txtSearchName"];
The problem I ran into is that this didn't find any control with the name of txtSearchName. While debugging I found this in myRequest object,
[5] "ctl00$cpMainContent$txtSearchName" string
Even though when I added textbox I gave it ID of txtSearchName but when page is rendered it is adding extra string from master page.
How can I stop this? I have to use master page so don't say not to use master page :)
Why is it doing that?
Update
While Googling and Binging I found that I can use Control.ClientID in this case so looking into it.
Update 2
As suggested below to add ClientIDMode="static" in the html of control or add it in page directive. What it does is, it keeps the ID static to txtSearchName but problem is this,
<input name="ctl00$cpMainContent$txtSearchName" type="text" id="txtSearchName" />
Here name is still using ctl00 and the code I showed above,
string strSearch = myRequest["txtSearchName"]
it still won't work because nvc collection is either searchable by index or name not the id directly.
==============
You need to add a ClientIDMode="Static" to the html of the textbox:
<asp:TextBox ID="txtSearchName" runat="server" ClientIDMode="Static" />
It happens to prevent duplicate ID's. Usually it happens when you use master pages as it contains nested pages
If you want all controls with ClientIDMode="Static", you can put it in the page header of the master file.
<%# Page Language="C#" ClientIDMode="Static" %>
If you are posting to another page that uses the same master page (called SiteMaster in my case), the name of the textbox should be same the same.
string val = Request[((SiteMaster)Master).txtSearchName.UniqueID];
If you're NOT posting to a page with the same master, well, then are you using the viewstate for the textbox at all since you're posting to another page? If not, just make the control a non asp.net control:
<input type="text" name="txtSearchName"/>
If you are using viewstate and posting to another page with a different master page, well, you should use PreviousPage.
Little late here. Appreciate #aquinas and #rudeovski ze bear. Interesting and good answers.
I'd same issue and I solved it differently.
In fact, I used a public Interface.
public interface ISearch
{
string SearchText { get; }
}
Then implement ISearch interface in two aspx page say One.aspx and Two.aspx classes.
--One.aspx-- (Where I'v added TextBox1, and Button1 and set Button1.PostBackUrl="~/Two.aspx")
public partial class One : System.Web.UI.Page , ISearch
{
public string SearchText
{
get
{
return TextBox1.Text;
}
}
}
--Two.aspx--
public partial class Two : System.Web.UI.Page, ISearch
{
protected void Page_Load(object sender, EventArgs e)
{
ISearch search = (ISearch) PreviousPage;
Label1.Text = search.SearchText;
}
public string SearchText
{
get
{
throw new NotImplementedException();
}
}
}
If your try to access the input element value in code behind on post back instead of for example:
var emailAddress = Request.Form["ctl00$ctl00$ctl00$ContentContainer$MainContent$MainContent$ContentBottom$ProfileFormView$emailaddress1"];
Use
var emailAddressKeyName = Request.Form.AllKeys.FirstOrDefault(a => a.Contains("emailaddress1"));
var emailAddress = Request.Form[emailAddressKeyName];
I have a simple ASP.NET Web User Control. It looks like this:
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="NewsArticle.ascx.cs"
Inherits="Website.Controls.NewsArticle" %>
<div>
<asp:Literal ID="ltlBody" runat="server" />
</div>
My code behind looks like this:
namespace Website.Controls
{
public partial class NewsArticle : System.Web.UI.UserControl
{
public String bodyText
{
//get { return ltlBody.Text; }
set { ltlBody.Text = value; }
}
}
}
On a .aspx page I have <asp:Panel ID="pNews" runat="server" />
In the code behind I have:
foreach (vwNews news in newsQuery)
{
NewsArticle article = new NewsArticle();
article.bodyText = news.Body;
pNews.Controls.Add(article);
}
Every time I run this code the newsQuery is populated correctly and I get to the line
aticle.bodyText = news.Body; and then I received the error article.bodyText threw an exception of type 'System.NullReferenceException'
I am not sure what is causing this error message or how to fix it. I would think that there should not be an issue. I tried creating a constructor for my Web User Control so that it would give default values to my properties but that didn't work. Any idea how to make this work? It doesn't seem like it should be that
To load a control programatically you need to use the Page.LoadControl() method. See this MSDN article
You have a typo within the code you've written. 'aticle' instead of 'article'.
Trying to set the value of a literal user control on my child master page via the code behind of the same master page.
Here is example of the code I am using:
Global.master
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="GlobalContentPlaceHolderBody" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
Template.master (child of Global.master)
<asp:Content ID="TemplateContentBody" ContentPlaceHolderID="GlobalContentPlaceHolderBody" Runat="Server">
<asp:Literal ID="MyLiteral1" runat="Server"></asp:Literal>
<p>This is template sample content!</p>
<asp:ContentPlaceHolder ID="TemplateContentPlaceHolderBody" runat="server">
</asp:ContentPlaceHolder>
Template.master.cs
protected void Page_Load(object sender, EventArgs e)
{
MyLiteral1.Text = "Test";
}
ContentPage.aspx
< asp:Content ID="ContentBody" ContentPlaceHolderID="TemplateContentPlaceHolderBody" Runat="Server">
</asp:Content>
Once I am able to achieve this, I will also need to be able to access content on the global and template master pages via content pages.
If I understand your scenario you want to have your content pages access items from your master pages. If so, you'll need to setup a property to expose them from your master page, and in your content page you can setup a MasterType directive.
Take a look at this post for an example.
Found a working solution. In the template.master (nested child master), I had to put the code in OnLoad event.
protected override void OnLoad(EventArgs e)
{
MyLiteral1.Text= "<p>MyLiteral1 Successfully updated from nested template!</p>";
base.OnLoad(e);
}
Very strange...
Basically, I am using the global master as the page that has code shared on every page, then I will have various nested pages to suit each website section. For the navigation nested template, I want to be able to show if the user is logged in and how many items in shopping cart.
If there is a better way to achieve this, I am open to suggestions.
EDIT: This is my answer when I thought you were trying to access a control on the child master from the parent master code behind.
You can use a recursive findControl function:
protected Control FindControlRecursive(string id, Control parent)
{
// If parent is the control we're looking for, return it
if (string.Compare(parent.ID, id, true) == 0)
return parent;
// Search through children
foreach (Control child in parent.Controls)
{
Control match = FindControlRecursive(id, child);
if (match != null)
return match;
}
// If we reach here then no control with id was found
return null;
}
Then use this code in your master page:
protected void Page_Load(object sender, EventArgs e)
{
//EDIT: if GlobalContentPlaceHolderBody isn't visible here, use this instead:
//Control c = FindControlRecursive("MyLiteral1", Page.FindControl("GlobalContentPlaceHolderBody"));
Control c = FindControlRecursive("MyLiteral1", GlobalContentPlaceHolderBody);
if(c != null)
((Literal)c).Text = "Test";
}