Access data on Page from Web Control - asp.net

I created a web control, and it needs some data from its parent page.
How can it access that data?
Update: Thank you for the quick solutions, however they don't work for me. Visual Studio doesn't recognize the name of the page as a class. I took the name from where the class is defind:
public partial class Apps_Site_Templates_CollegesMain : cUICommonFeatures
(cUICommonFeatures inherits from System.Web.UI.Page)
But in the control, when I define
protected System.Web.UI.Page parentPage;
parentPage = (Apps_Site_Templates_CollegesMain)Page;
I get a compliation error:
The type or namespace name 'Apps_Site_Templates_CollegesMain' could not be found (are you missing a using directive or an assembly reference?)
I feel like I'm missing something really basic here, and I'll probably be very embarrassed when I get an answer, but I do need help....

If the parent page class is named lets say ParentPage, you can do this within the control:
ParentPage page = (ParentPage)this.Page;
Then you can access the properties and methods on ParentPage. If you have more pages using the same control, you should use an interface on the parent page to access the properties on the page.
IParentPage page = (IParentPage)this.Page;
Does that answer your question?

Controls should be written to be independant of what page they're on. If the control needs a piece of data, then it should expose a public property which is of the type of the data that it needs. The page it is on wo uld then set that property to the data that the control needs. This permits the control to be used on another page, or even made part of a UserControl and that UserControl then used on the parent page.

There are many ways to do that. I think the best one is adding a property for the data control needs and in your page set this property.
Also you can access to your page from your control like that :
string dataYouWant = ((YourParentPageName)Page).GetData();
Or you can add the data to viewstate, and read it from the child controls.
But as I said, I would choose the first one.

All Controls (server controls, usercontrols and custom controls) expose a property Page which allows you to access the containing Page instance from the code of the control.
Therefore, you could simply do:
// In Usercontrol code:
MyParentPage parentPage = this.Page as MyParentPage;
if (parentPage != null)
{
// Access the properties of the Parent page.
string t = parentPage.Title;
}
The article "Mastering Page-UserControl Communication" offers a good beginners introduction to control-Page interactions.

Related

Are ASP.net Content Web Forms able to access variables declared in the Code Behind section of it's Master Page?

I have a Master Page which controls the styling of my site. In the Code Behind, there are a few class instances instantiated as well as variables. These classes validate user access and then create user objects
I have a few Web Content Forms which carries out instructions based on the user objects. So far it seems that on each Web Content Form I have to create new instances of the classes found on the Master Page. This is doubling my work for every Web Content Form.
Is there anyway I can inhereit Classes and objects instantiated in the Master Page Code Behind?
Expose the objects (and even controls) as public properties (get only for controls) on the Master page. Then, in each aspx page you want access to these objects, add the following declaration at the top:
<%# MasterType VirtualPath="~/MyMasterPage.master" %>
As #Kristof points out, simply access your properties like Master.PropertyName
Also, you can determine if it makes sense to store the objects in the users Session (don't forget that they must be serializable if you use DB for session state). I do this often and control access to them via properties in a base Page class that all my pages inherit from. Actually, I have a base master, page, and usercontrol so I have access to the same properties (for me it's CurrentUser) everywhere.
I believe you can if you make the properties public.
Then in your child-page you can make the call something like this:
SiteMaster master = (SiteMaster)this.Master;
master.MyProperty = 0;
Where SiteMaster is the class for your master page. (SiteMaster is the default for the app templates)
Though my mind can deceive me, I haven't done it for a while...

Best way to set master page properties in content page in asp.net?

There are different ways to set the title for content pages from Master page
by findcontrol
by creating property in master page and setting the value in content page
As both method requires an object creation of master page which will be little heavy
myMasterPage myMaster = (myMasterPage)this.Master;
so I have tried it by creating a class and it worked -
public class clsmaster
{
public static clsmaster objmaster = new clsmaster();
public strtitle {get;set;}
}
Now I just need to access this static object and set the property in the content page and in the master page I just need the controls to take the value from this class (clsmaster).
I would like to know which one is the better approach and why with description please?
I generally advise creating a BasePage class of some sort that encapsulates the behavior you want through all of your pages, these objects are assumed to always have the same master page, if you need other setups then you can create other objects as necessary.
From there you can create some properties or methods to allow the BasePage objects to access the master page or its associated properties in a very easy to code way such as this.Title = "MyTitle"
You can get fancier and create some virtual methods on your BasePage class that you can then override on the physical pages as necessary, to set titles, etc, as needed, without ever grabbing the Master page object directly (which yes, is annoying and ugly). This might look something like this.Title = GetTitle(); (GetTitle is a virtual method on the BasePage that is overridden in the child pages as needed for those pages you want to set a title for).
This makes strong use of inheritance and lets you add functionality to all of your pages very easily, it may be overkill for what your doing but I've never found a situation that was too simplistic for this architecture, it just works really well. I personally find this design far better than constantly using FindControl(), which tends to be error-prone when control ID's change, etc.
FindControl() is bad because if the control ID's change, then you might forget to update them in the FindControl reference, and now it'll break the next time its executed, I stay well away from static stuff like this if at all possible for this very reason, it's a cheap, quick but error-prone solution.
Accessing the Master page directly isn't inherently bad, I just can't stand stuff like:
myMasterPage myMaster = (myMasterPage)this.Master
Gets old, is uglier than it needs to be, wrap it in an accessor property at the very least ;)
I like the following better:
Title = "My Title"; // Property
or
Title = GetTitle(); // Virtual method

Add 'Current' property to ASP.NET control

I have some control. I add one instance of this control to every Page in OnInit event and I want to access this control in other places in this way: Sample.Current
public class Sample : Control
{
public static Sample Current
{
get
{
// ???
}
}
}
Can you tell me what is the best way to do this property implementation?
It would be good to have a bit more detail - what is this class' purpose? But I'll attempt to help anyway:
You'll be able to access that control from within code on the page , if it's referenced in the code and not added dynamically somehow at runtime. ie if it's a variable of the page declared like:
Sample ctrl = new Sample();
Then later you can reference it using ctrl.Current in your code.
FYI - if you want a place to reference classes and variables for a page's lifecycle, you may want to check out HttpContext.Current.Items http://www.mikeduncan.com/3-hot-uses-for-httpcontextcurrentitems-they-wont-tell-you-about/ It's like a session bag that only exists for a single page request - for example if you have a class that holds information about a user that you need to access many times from many different controls on the page, you could just stick that class into the Items collection and then reference it from any code that runs on your page.
HTH,
Lance

ASP.NET 2.0 - Parent Page Class not accessible from custom control

1) I've page class
public partial class MyDelivery : System.Web.UI.Page
2) ASCX is in different subfolder
public partial class MyControls_Hello_Bye : System.Web.UI.UserControl
I am unable to access #1 parent page class from control
This problem annoyed me for quite a while. I don't think my solution is perfect, but it sure helps my junior developers in coding. We have a base user control that all user controls inherit and we (like you) we have a base page class that all pages must inherit (team rule). In the user control is a property called ParentForm which is strongly typed to the specific page type that will contain it (the page baseclass if that is variable or unknown at the time).
During the load event of the page, we manually set the Parentform Property of all user controls (we do this in our master page for all master page level controls as well).
protected Page_Load(object sender, System.EventArgs e)
{
this.myControl.ParentForm = this;
this.myControl2.ParentForm = this;
}
This provides immediate access from any user control back to the page and any of its exposed methods. It also provides a standardized (within our team) method of allowing controls to communicate between themselves through an interface in the ParentForm.
Our standard is to perform this assignment manually. For me this was a personnel consideration to make sure developers are aware of the controls they are adding (not setting the ParentForm will cause null reference exceptions if you attempt to access it obviously). If you wanted to perform this setting automagically, you could use the base class's Page_InitComplete event to cycle through any user controls and set the ParentForm to "this" that way.
Being in a different directory would get visual studio to give them different namespaces by default, causing the parent page class not to visible to the control.
Make sure the namespace declarations of both classes are the same, or import the parent page class namespace to the contorl with the using statement.

How To: Use AJAX in an ASP.NET Custom Server Control

Does anyone know of a good tutorial that demonstrates using an existing AJAX control extender in a Custom ASP.NET Server Control?
I do not want to build a "Custom AJAX Server Control". I want to build a Custom Server Control that uses an existing AJAX control extender.
I would like to combine an asp:TextBox, asp:ImageButton, asp:CustomValidator (with client side javascript from an embedded resource), and an ajax:CalendarExtender into one custom server control. Or has this already been created?
Any help would be greatly appreciated. Thanks.
UPDATE: Basically, I would like to create a CompositeControl that has an ajax:CalendarExtender as a child control.
Sounds like what you're after is a composite control. They are pretty much exactly like a user control only instead of using the ascx file to create the controls you create them all programmatically. The big advantage of doing this over using a user control is you end up with something you can put in an assembly and use in different projects.
A composite control can inherit from either Control or WebControl. I personally usually find Control more useful to inherit from because I usually don't need a lot of the extra stuff you get from WebControl such as the styling properties since I usually just style through a single CssClass property.
You'll also need to make sure your class implements the INamingContainer interface. This will make sure that each child control will automatically get a unique name if the control is used multiple times in the same parent container.
The most important thing to do when creating a composite control is to override Control's CreateChildControls method. All the logic for actually creating the controls should go in here. The framework will automatically make sure that this gets called at the right time in the page lifecycle.
Here's a little example:
public class MyCompositeControl : Control, INamingContainer
{
protected override void CreateChildControls()
{
Controls.Clear();
var textbox = new TextBox();
textbox.ID = "TextBox1";
Controls.Add(textbox);
if (!Page.IsPostBack || !IsTrackingViewState)
{
// make sure you set the properties after
// you add it to the parent or the viewstate
// won't save properly
textbox.MaxLength = 30;
}
var button = new Button();
button.ID = "Button1";
Controls.Add(button);
if (!Page.IsPostBack || !IsTrackingViewState)
{
button.Text = "Save";
}
}
}
I don't think ASP.NET AJAX should complicate this much. The only thing I can think of ist you'll need to make sure that you create a ScriptManager on whatever page the composite control will be added to.
There's a full example of this on the MSDN site. There's another nice example on this blog.
What you want is to build a user control and not a custom control most probably. A user control is a composite control whereas a custom control is a control built either from the ground up either derived from a basic control.
I would suggest you search on MSDN. I have seen several good articles about that topic in their magazines over the last year or two, that have been fairly thorough. But I don't have links to them and I'm too lazy to Google for you. :\

Resources