How To retrieve a control in a Master Page from Content Page - c#

When I asked recently a question about how To retrieve a control in a Master Page from Content Page.
Many peoples suggest me to use this code from my Content Page:
Label lbl = this.Master.Page.FindControl("uxLabel") as Label;
//Note any server controls defined in the master page could be not be accessible even after a cast is performed, because they could be marked as protected
This approach certainly works, I also realize that is available a strongly-typed solution that doesn't involve casting the Master property.
In the Master Page place:
public Label HeaderLabel
{
get { return uxLabel; }
}
Using a MasterType in the Content Page:
<%# MasterType VirtualPath="~/Templates/WebsiteMasterPage.master" %>
Now it is pretty easy find the control from the Content Page:
protected void Page_Load(object sender, EventArgs e)
{
this.Master.HeaderLabel.Text = "Any Text here!";
}
I would like to know:
what do you think about this
approach?
any other solution?
Thanks for your time

My answer is "why not?".
Both are for me good approaches but first needs less coding in order to get started with it, since you don't need to initialize any class field and design properties. But control must be found during run-time.
Second approach, call it "typed approach", is just cast to specific master page class and you get access to any class-specific member.
What would be the main problem of "typed approach"? You need a reference to the class library (assembly) in order to access to such master page's members, which wouldn't be desirable in some scenarios. For example, you've a control library and you want to access a mandatory master page's control which provides some behaviors needed to work with some library's control. You would need to reference your web client assembly, but you can't do that because you reference your control library in the web client itself, and this is a circular reference.
Tools, approaches are there for use in specific scenarios. Why not? answer can be expanded to why not to use "typed approach" if it's needed and your scenario is compatible with that concept?.

Related

Re-using another page section

I have created a web page that I use as a small dashboard to hold issue or no issue. It works great. The page uses an .aspx and .aspx.cs. I would like to be able to reuse the information on this page on other pages. My site already uses master pages and I have not been able to find an easy way to include this information.
How can I use an include from a page that has coding in the code behind easily?
Typically you use Web User Controls for this.
Web User Controls allow you to package up other controls into one that you can drop onto multiple pages. They are great for common UI items such as address entries, dashboards, etc. Basically anything that needs to be the same across multiple pages.
At the risk of seeming very obvious - do you mean usercontrols. These will allow you to reuse chunks of functionality across your site.
I guess this question falls into two categories: User Controls, and Code Reuse. Not sure which one you are after.
User Controls
If you are talking about the controls on your page you will want to create a common user control.
Code Reuse
You need to create a common class (whether it is static or not depends on how you intend to use it) and define functions within that class.
For instance, lets say you have a page that you want to print "Hello World!" on any aspx/.cs page.
You could do this
public static class MyClass
{
public string PrintHelloWorld()
{
return "Hello World!";
}
}
Then you call it from any of your pages like so:
MyClass.PrintHelloWorld();
Right click on the project > Add New Item...
Select User Control (.ascx)
Put your markup & code behind there.
Then you add that control in any other page (includding other controls [although I wouldn't recommend that])
It sounds like you may want to create an ascx User Control.
http://msdn.microsoft.com/en-us/library/ie/2x6sx01c.aspx

Using the same code behind file for multiple .aspx pages

We are developing a site inside a CMS that pushed files to our production server. If the .apsx pages created share the same code behind file, will this cause a problem?
Why don't you let both pages inherit from the same class?
public class MyPage : System.Web.UI.Page
{
// common logic that both pages should have
protected void Page_Load(object sender, EventArgs e)
{
}
}
public partial class PageA : MyPage
{
// specific logic for page A
}
public partial class PageB : MyPage
{
// specific logic for page B
}
Yes. It is technically possible, but it is not a supported way of using ASP.NET and there will likely be gnarly difficulties with it.
You should use User Controls or AppCode instead.
I would suggest to avoid such design, so each page should has own code behind file.
Also take a look at the following ASP.NET features whcih can simplify sharing of common layout and behaviour across the web pages:
Master pages (.master), basically multiple pages which has the same layout could use a shared master page which provides the common layout and supporting code behind logic. Moreover - You can switch master pages in runtime and master pages could be nested, so Master Page could be placed inside of an other Master Page, this gives you a much of freedom and flexibility to design your web application layout and separate responsibilities as well.
User Controls (.ascx), it worth to separate concerns and split page by a set of controls, for instance, it could be LoginControl.ascx,, AdControl.ascx, SearhcControl.ascx, so you keep a code of page clean and each control provides specific functionality and own layout.
Inheritance, so basically set of pages have the same base class which inherited from the Page class (I would not suggest use this approach massively, one base page it is enough)
You may use other common development techniques like dependency injection to share code across multiple pages, this depends on particular case and business goals which were considered under the hood.

Problem With Custom Control on Page Using a MasterPage

I have a content page which has a related master page.
I register a prefix <%# TagPrefix ..... and can load other custom controls at that namespace.
However, one particualar control at the same namespace, when added to the aspx page, breaks it.
The control in question inherits from asp:Panel, has a parameterless constructor, defines a few public accessors, and creates some standard child controls, and nothing much else.
Are there some fundamental restrictions to creating custom asp controls that I am breaking unknowingly?
Add the control back to the page. Delete the designer file for the page: .aspx.designer.cs
Then right click on the page and select Convert to Web Application. This should give you the actual error the page has when attempting to write the control definition to your designer file.
I suspect there is a compilation error in your custom control.
My control was attempting to access Page.Header which was null as the master page had not marked the tag with runat="server".
I guess that is a fundamental restriction that I was looking for...

Web Control added in .master control type not found in child page

I have a Web Site project, and within it I have a user Web Control defined in an ascx file.
The control is added to the Site.Master, and it shows up correctly on the page and everything is fine.
I need to override some of the control's fields on one of the pages that derive from Site.Master.
// In OnLoad:
MyControlName control = (MyControlName) Page.Master.GetBaseMasterPage().FindControl("controlID"));
The issue is that MyControlName doesn't register as a valid Type on the child page. If I add a second instance of the control to the child page directly, the above works as needed, but if the control isn't placed directly on the page, and instead is only defined in the master page, the type is undefined. The control is not in a namespace, and is defined within the project, so I don't know why it is having such an issue location the appropriate type.
If I put a breakpoint in the OnLoad, the type listed for the control is ASP.my_control_name_ascx, but using that does not work either.
Why can't the child class reference the correct type? Can I fix this?
Thanks!
The control does not have global scope over the entire project. It will only be selectable as a type on pages where the control is registered. So you have to register the control on the child page:
<%# Register src="WebUserControl.ascx" tagname="WebUserControl" tagprefix="uc1" %>
You will need to add a register tag like above to the top of your child aspx page.
The other option is you could create an interface for the control which exposes the properties or methods you want to access, and put the interface in app_code or some other globally accessible place, then have the control implement the interface, and cast the control to the interface.
The following code works for me:
DropDownList ddlLanguage = (DropDownList)Page.Master.FindControl("ddlLanguage");
I take it GetBaseMasterPage() is your own method? What happens if you try:
MyControlName control = (MyControlName)Page.Master.FindControl("controlId");
?
Not a direct answer to your question, but you might find the #MasterType directive useful.
If you add a line like
<%# MasterType TypeName="ClientName.SiteName.MasterPages.SiteMaster" %>
to the top of your ASPX page, you should be able to refer to the master page in code without having to cast it. This might make it easier for the code to find your control, perhaps?
You could end up with a line like:
// In Page.OnLoad:
MyControlName control = Page.Master.MyControl;
and then expose a new property in your master page that wraps the FindControl call:
// In Site.master.cs
internal MyControlName MyControl
{
get { this.FindControl("controlID"); }
}
Hope this helps!

How to access .Net element on Master page from a Content page?

Is it possible to access an element on a Master page from the page loaded within the ContentPlaceHolder for the master?
I have a ListView that lists people's names in a navigation area on the Master page. I would like to update the ListView after a person has been added to the table that the ListView is data bound to. The ListView currently does not update it's values until the cache is reloaded. We have found that just re-running the ListView.DataBind() will update a listview's contents. We have not been able to run the ListView.DataBind() on a page that uses the Master page.
Below is a sample of what I wanted to do but a compiler error says
"PeopleListView does not exist in the current context"
GIS.master - Where ListView resides
...<asp:ListView ID="PeopleListView"...
GISInput_People.aspx - Uses GIS.master as it's master page
GISInput_People.aspx.cs
AddNewPerson()
{
// Add person to table
....
// Update Person List
PeopleListView.DataBind();
...
}
What would be the best way to resolve an issue like this in C# .Net?
I believe you could do this by using this.Master.FindControl or something similar, but you probably shouldn't - it requires the content page to know too much about the structure of the master page.
I would suggest another method, such as firing an event in the content area that the master could listen for and re-bind when fired.
Assuming the control is called "PeopleListView" on the master page
ListView peopleListView = (ListView)this.Master.FindControl("PeopleListView");
peopleListView.DataSource = [whatever];
peopleListView.DataBind();
But #palmsey is more correct, especially if your page could have the possibility of more than one master page. Decouple them and use an event.
Option 1 :you can create public property of your master page control
public TextBox PropMasterTextBox1
{
get { return txtMasterBox1; }
set { txtMasterBox1 = value; }
}
access it on content page like
Master.PropMasterTextBox1.Text="SomeString";
Option 2:
on Master page:
public string SetMasterTextBox1Text
{
get { return txtMasterBox1.Text; }
set { txtMasterBox1.Text = value; }
}
on Content Page:
Master.SetMasterTextBox1Text="someText";
option 3 :
you can create some public method that works for you
these approach is not so useful but it helps if you just want to use some limited and predefined control
One think to remember is the following ASP.NET directive.
<%# MasterType attribute="value" [attribute="value"...] %>
MSDN Reference
It will help you when referencing this.Master by creating a strongly typed reference to the master page. You can then reference your ListView without needing to CAST.
you can access with the code this.Master.FindControl(ControlID) which control you wish. It returns the reference of the control, so that the changes are effective. about firing an event could not be possible each situation.
Assuming your master page was named MyMaster:
(Master as MyMaster).PeopleListView.DataBind();
Edit: since PeopleListView will be declared protected by default, you will either need to change this to public, or create a public property wrapper so that you can access it from your page.

Categories