Can not access control from nested master page in content page - asp.net

I am using nested master pages where i want to use Label control from nested master page and update its text. but it is not accessing. When i removed outer master page then it is working fine. Following is the markup and code.
OUTER MASTER
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="Roster.Site" %>
NESTED MASTER
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="RoasterMaster.master.cs" Inherits="Roster.RoasterMaster" MasterPageFile="~/Site.Master" %>
<%# MasterType VirtualPath ="~/Site.Master" %>
CONTENT PAGE
<%# Page Language="C#" AutoEventWireup="true" Inherits="RequestsView" CodeBehind="ViewRequestsByPM.aspx.cs" MasterPageFile ="~/Roaster/RoasterMaster.Master" Title ="Roaster- View Requests by PM" %>
<%# MasterType VirtualPath ="~/Roaster/RoasterMaster.Master" %>
CONTENT PAGE CODE
protected void Page_Load(object sender, EventArgs e)
{
Label lblTitle = new Label();
lblTitle =(Label)Master.FindControl("lblTitle");
lblTitle.Text = "View Roaster Request";
}
What is going wrong with the implementation. Please help. Thanks

You can add the below code snippet in
NESTED MASTER PAGE
public string PageTitle { get; set; } // In page_load
lblTitle.Text = PageTitle;
CONTENT PAGE CODE
this.Master.PageTitle = "YOUR TEXT";
This will work for you...

Assuming that your label is in Roster master page, you can simply add method to set the text in master page code behind. For example,
in RoasterMaster.master.cs
public void SetTitle(string value)
{
this.lblTitle = value;
}
And in content page code
Master.SetTitle("View Roaster Request");
In case, your label is in outer master then you can similarly forward the call to the outer master from roster master code.
EDIT
Your code does not work in nested master case scenarios because Master page contents get added within page control hierarchy with different naming container. FindControl method does not span multiple naming containers which is the case here - because of nesting you have nested naming containers. Page.Master would give you outer naming container but your label might be lying in inner naming container. One of the way, is to write your own find control implementation that will recurs within the control tree but really it does not make sense - I would rather use above code which is more efficient and more importantly better maintainable.

Related

Get Control by URL

I'm currently on my first asp.net WebForms Site. To display different Sites I'm loading a control into a Placeholder in my masterpage.
example: UserControl uc = this.LoadControl("~/controls/home.ascx") as UserControl;
this goes over my default.aspx codebehind file. I'm now struggeling with fill in another control based on the URL. I know that you can get for example an ID (if my-domain.com/default.aspx?id=1 then show control blabla) but is it possible that I read out the URL and instead of the ID a string? for examples:
my-domain.com/home -> this goes over my default.aspx, but shows de home controller
my-domain.com/contact-> this goes over my default.aspx, but shows de contact controller
Can I check if it's "/home" and then show the home-control?
Has anyone an idea, how I could solve this problem?
Thanks guys :)
Here are a few code snippets:
masterpage.master:
<asp:ContentPlaceHolder id="content" runat="server"></asp:ContentPlaceHolder>
default.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/masterpage.master" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="myproject._default" %>
default.aspx.cs:
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ContentPlaceHolder content = this.Master.FindControl("content") as ContentPlaceHolder;
displayControl(content);
}
private void displayControl(ContentPlaceHolder content)
{
UserControl uc = this.LoadControl("~/controls/home.ascx") as UserControl;
if ((content != null) && (uc != null))
{
content.Controls.Add(uc);
}
}
}
home.ascx:
my HTML-Page
My folders are in the following structure:
css
img
javascript
App_Data
bin
obj
controls
home.aspx
contact.aspx ... etc.
default.aspx (with the code behind file .cs)
masterpage.master
misc: web.config and other files and folders...
If you want your site to go from domain.com/default.aspx?id=1 to domain.com/home, or domain.com/login you need to enable Friendly URLs and setup a route in your WebForms.
Scott Hanselman has a walk-through at the following link...
http://www.hanselman.com/blog/IntroducingASPNETFriendlyUrlsCleanerURLsEasierRoutingAndMobileViewsForASPNETWebForms.aspx

Make control public in designer generated file

It there any way to tell the ASP.NET .designer.cs code generator to create public controls instead of protected?
.master.designer.cs file:
/// <summary>
/// btnLanguageEN control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.LinkButton btnLanguageEN;
.master file:
<asp:LinkButton runat="server" ID="btnLanguageEN" OnClick="btnLanguageEN_Click" Text="ENG" />
Why I need it? I am trying to access to master page controls from child page:
.aspx file:
<%# MasterType TypeName="www.MainMaster" %>
.aspx.cs file:
Master.btnLanguageEN.Text = "123";
Here I receive an error stating that btnLanguageEN is protected.
Rather than modify the designer generated code, reference the control through the Page's Master property using the FindControl method.
You'll need to add the following directive to the top of your child page (if it's not already there) to reference the master page:
<%# MasterType virtualpath="~/Masters/Master1.master" %>
Then, in your child page's code behind, you can do things like the following.
void Page_Load()
{
// Gets a reference to a LinkButton on the master mage.
// a ContentPlaceHolder
LinkButton mpLinkButton = (LinkButton) Master.FindControl("btnLanguageEN");
if(mpLinkButton != null)
{
mpLinkButton.Text = "123 - Labelled by Child Page";
}
}
Reference: http://msdn.microsoft.com/en-us/library/xxwa0ff0.aspx
Create a strongly typed reference to your master page by including this on your ASPX page.
<%# MasterType virtualpath="~/Masters/Master1.master" %>
On your Master Page, create a property. This will make the control available from other classes..
public Button btnLanguageENMaster
{
get {return btnLanguageEN;}
private set;
}
Then from your regular page code behind you can do this...
Master.btnLanguageENMaster.Text = "Hello, world!"

InstantiateIn and user controls

I want to add my user control in InstantiateIn like this:
public void InstantiateIn(Control container)
{
PIMVisualizer pimVisualizer = new PIMVisualizer();
container.Controls.Add(pimVisualizer);
container.Controls.Add(new Button() {Text="asdf"});
}
but the control doeas not appear on the page (the button does). The control is trivial, I am just testing the approach:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="PIMVisualizer.ascx.cs" Inherits="PIMVisualizer" %><asp:Label ID="Label1" runat="server" Text="UC"></asp:Label>
but still, why does not the text "UC" appear onthe page?
You have to load UserControls, do not create them via constructor.

Accessing ASP.NET Master Pager public properties in child page

I'm embarrassed to ask this here because it's clearly been duplicated several times already on StackOverflow. I've read a lot of stuff including:
http://msdn.microsoft.com/en-us/library/xxwa0ff0
http://msdn.microsoft.com/en-us/library/c8y19k6h.aspx
http://www.velocityreviews.com/forums/t110056-cannot-access-strongly-typed-properties-in-master-page.html
I think I've done exactly what those article say, but it's not working for me.
Here's the top of my master page, named "MasterNoNews.master":
<%# Master Language="C#" %>
<%# Import Namespace="MyMediHealth.DataAccess" %>
<%# Import Namespace="MyMediHealth.DataAccess.Containers" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public virtual UserContainer CurrentUser;
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
CurrentUser = new MembershipQueries().getUserFromUserIdName(Page.User.Identity.Name);
}
</script>
Here's the top of my child page, named "MyProfile.aspx":
<%# Page Title="" Language="C#" MasterPageFile="~/MasterNoNews.master"
AutoEventWireup="true" CodeBehind="MyProfile.aspx.cs"
Inherits="MyMediHealth.Interface.MyProfile" %>
<%# MasterType VirtualPath="~/MasterNoNews.master" %>
Here's the code-behind on my child page, named "MyProfile.aspx.cs" that's not working:
using System;
using System.Web.UI;
using MyMediHealth.DataAccess.Containers;
using MyMediHealth.DataAccess;
namespace MyMediHealth.Interface
{
public partial class MyProfile : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// doesn't work
UserContainer user = Master.CurrentUser;
// also doesn't work
UserContainer user = ((MasterNoNews)this.Master).CurrentUser
}
}
}
In the first case, VS is telling me System.Web.Ui.MasterPage does not contain a definition for CurrentUser. In the second case, VS says the type or namespace 'MasterNoNews' could not be found.
What am I doing wrong?
You'll probably still need to move the master page's code to the code behind, but if you put this,
<%# MasterType VirtualPath="~/MasterPages/Site.master" %>
on the aspx page you'll be able to access the master page's public methods directly without all that casting. Like so:
UserContainer user = Page.Master.CurrentUser
If you're using the master page's code from loads of child pages then I'd create an interface and have the master page implement it.
This will not work because you have created properties within Master page (and not code-behind). Typically, master page code would get compiled dynamically and a class name (depending on file name) will be created in a temporary assembly. As you are not reffering to this generated class name within temp assembly, you get error. Correct way will be to have code behind file for the master. For example, master will be
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="MasterNoNews.master.cs" Inherits="[Your Namespace].MasterNoNews" %>
And in code-behind file (MasterNoNews.master.cs) have your properties:
namespace [Your Namespace]
{
public partial class MasterNoNews : System.Web.UI.MasterPage
{
public virtual UserContainer CurrentUser;
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
CurrentUser = new MembershipQueries().getUserFromUserIdName(Page.User.Identity.Name);
}
}
}
Now the second syntax would work i.e.
UserContainer user = (([Your Namespace].MasterNoNews)this.Master).CurrentUser

Asp.net: Can we use MasterPage's viewstate in ContentPage?

Asp.net: Can we use MasterPage's viewstate in ContentPage ?
From a Content Page you can refer to a MasterPage through the Master Property. Create a Property on the Master Page that uses its getter and setter to store its value in ViewState, like so:
string MyProperty
{
get { return ViewState["MyProperty"] as string; }
set { ViewState["MyProperty"] = value; }
}
Obviously you could make that code safer by testing for nulls and what-not...
Here's the important bit: Viewstate elements are only accessible from the controls that added them so you need to refer back up the tree.
You can also strongly type the Master property on Page by using the <%# MasterType %> directive in your ASPX file, thusly:
<%# MasterType VirtualPath="~/masters/SourcePage.master"" %>
HTH.

Resources