I am trying to set a label in master page from content page, not using FindControl. So, in master page I declared:
public partial class MainMasterPage : System.Web.UI.MasterPage
{
public string UserOfficeLabel
{
get { return lblUserOffice.Text; }
set { lblUserOffice.Text = value; }
}
public string OfficeLocationLabel
{
get { return lblOfficeLocation.Text; }
set { lblOfficeLocation.Text = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
....
}
}
"UserOfficeLabel" and "OfficeLocationLabel" are labels on master page. Then in content page (.aspx) I added the following directive under "Page" directive:
<%# MasterType VirtualPath="~/Main/MainMasterPage.master" %>
In conent page's code behind (.cs file) I try to access/set the label:
Master.UserOfficeLabel = ...
but UserOfficeLabel is not an option for Master (VS Intellisense does not list it as an option). When I add it anyway, it says "MainMasterPage.UserOfficeLabel is inaccessible to its protection level"
I think you can find what you are looking for here:
http://odetocode.com/blogs/scott/archive/2005/07/16/mastertype-in-asp-net-2-0.aspx.
In theory when you compile you should see the code below inside a partial class
Public Shadows ReadOnly Property Master() As otc
Get
Return CType(MyBase.Master,otcMaster)
End Get
End Property
I've done something like what you are trying by declaring a variable
Dim LocalMasterPageRef As MyMasterPageName
LocalMasterPageRef = CType(Me.Master, MyMasterPageName)
...
LocalMasterPageRef.xxxx
Hope it helps.
Related
i want to access a span on a asp.net master page from child page, so i'd made a public property on that master page-->
public partial class Ui_MasterPage_UI : System.Web.UI.MasterPage
{
public int tax = 0;
public string notification
{
set
{
(this.FindControl("notification") as HtmlAnchor).InnerText = value.ToString();
}
}
------------------//some code
}
and now wants to access this from a child page to set some text into that htmlanchor tag,
so that i'd written some script-->
child page
public partial class Ui_ProductDetails : System.Web.UI.Page
{
protected void ListView_ProductDetails_itemcommand(object sender, ListViewCommandEventArgs e)
{
Master.notification = "some text"; ////////showing error
------------------//some code
}
------------------//some code
}
but getting the syntax error
i think there is some problem in above code,,,,,so plz review it......
is there any other way to do this ???
thnku
You need to cast the Page.Master property to the type of your Master Page.
((Ui_MasterPage_UI)Page.Master).Notification = "some text";
There is parent user control, as seen below.
<%# Control Language="C#" AutoEventWireup="true" CodeFile="TestUserControl.ascx.cs" Inherits="TestUserControl" %>
<%# Register Src="~/UserControls/ChildUserControl.ascx" TagName="ChildUserControl" TagPrefix="FLI" %>
<div>
<FLI:ChildUserControl ID="child1" runat="server"/>
</div>
The child usecontrol has pulic property MatchDescription, which is set in the Page_Load of the parent control. I want to cache multiple versions of the child control, based on the MatchDescription property.
Problem is, the MatchDescription property cant be set in Page_Load, as the cached copy of the child control is used once its available.
How can i fix this problem?
Thanks!
It looks like using GetVaryByCustomString is the way to go here. My proof of concept consisted of the following:
WebUserControl.ascx: the test control. It has a single public property MatchDescription.
Global.asax: to override the GetVaryByCustomString method.
WebForm.aspx: a simple form to host the control.
WebUserControl.ascx
Add the following to the markup on the control:
<%# OutputCache Duration="120" VaryByParam="none" VaryByCustom="MatchDescription" %>
This specifies the duration (in seconds) to cache the control and VaryByCustom="MatchDescription" specifies the name of the parameter we will be caching on.
WebUserControl.ascx.cs
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public string MatchDescription { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
object description = this.Context.Application["MatchDescription"];
if (description != null)
{
this.MatchDescription = description.ToString();
}
else
{
this.MatchDescription = "Not set";
}
Label1.Text = "Match description: " + this.MatchDescription;
}
}
This will check for the existance of the MatchDescription value. Because of the way the code in the parent page works, you should never see "Not set", though in your implementation it may be useful just in case the value is not set.
Global.asax
Add a Global.asax file to your project and add in the following method:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "MatchDescription")
{
object description = context.Application["MatchDescription"];
if (description != null)
{
return description.ToString();
}
}
return base.GetVaryByCustomString(context, custom);
}
This is the bit that checks for the MatchDescription associated with the cached control. If it is not found the control will be created as normal. context.Application is used because we need a way to communicate the description value between the parent page, the user control and the global.asax file.
WebForm.aspx.cs
public partial class WebForm : System.Web.UI.Page
{
private static string[] _descriptions = new string[]
{
"Description 1",
"Description 2",
"Description 3",
"Description 4"
};
protected override void OnPreInit(EventArgs e)
{
//Simulate service call.
string matchDescription = _descriptions[new Random().Next(0, 4)];
//Store description.
this.Context.Application["MatchDescription"] = matchDescription;
base.OnPreInit(e);
}
protected void Page_Load(object sender, EventArgs e)
{
var control = LoadControl("WebUserControl.ascx") as PartialCachingControl;
this.Form.Controls.Add(control);
//Indicate whether the control was cached.
if (control != null)
{
if (control.CachedControl == null)
{
Label1.Text = "Control was cached";
}
else
{
Label1.Text = "Control was not cached";
}
}
}
}
Note that in this code I am making/simulating the service call in the OnPreInit method. This is necessary as it occurs in the page lifecycle before the GetVaryByCustomString method.
Keep in mind that if a control has been cached, accessing it in the Page_Load method, for example, will require code of this form:
if (control is PartialCachingControl &&
((PartialCachingControl)control).CachedControl =!= null)
{
WebUserControl1 userControl = (WebUserControl1)((PartialCachingControl)control).CachedControl;
}
References:
My answer was inspired by: Any way to clear/flush/remove OutputCache?
I found the Pre_Init hint in this question:
Output Caching - GetVaryByCustomString based on value set in PageLoad()
This KB article discusses why the PartialCachingControl.CachedControl property can always return null:
http://support.microsoft.com/kb/837000
I have a user control on the master page and I would like to pass in a value into that user control from the subpage, how would I be able to pass the values?
This control is in the master page
<%# Register TagPrefix="test" TagName="Data" Src="controls/TEST.ascx" %>
This code variable is within the user control
public partial class Controls_TEST : System.Web.UI.UserControl
{
private string _Title;
public string Title
{
get { return _Title; }
set { _Title = value; }
}
}
Code within the subpage
public partial class sub_page : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Controls_Test m = LoadControl("~/Controls/TEST.ascx");
m.Title = "TEST";
}
}
Note the sample code within subpage does not work because it cannot find that user control within the subpage.
I've tried Page.Master.FindControl and it also does not work for me. PLease help.
Use properties to communicate from your Page to your MasterPage and use properties to communicate from your MasterPage to the UserControl.
To get a reference to the control in your MasterPage you should provide a public property that returns it:
For example(in MasterPage):
public Controls_Test MyControl
{
get
{
return Controls_TEST1;
}
}
And you can call this property from one of your ContentPages in this way(f.e. if your master's type is named "SiteMaster"):
protected void Page_Load(object sender, EventArgs e)
{
((SiteMaster)Page.Master).MyControl.Title = "TEST";
}
As a rule of thumb: the more you encapsulate your controls, the more robust ,failsafe, maintanable and extendable your code will be.
Hence it would be better to provide only access to the Title rather than to the whole UserControl.
In MasterPage:
public String Title
{
get
{
return Controls_TEST1.Title;
}
set
{
Controls_TEST1.Title = value;
}
}
In the ContentPage:
((SiteMaster)Page.Master).Title = "TEST";
On this way you could change the logic and controls in your UserControl and MasterPage without having problems in your pages that already have accessed the UserControl directly.
Here is my master page code behind:
namespace mysite.MasterPages
{
public partial class Main : System.Web.UI.MasterPage
{
public bool isLoggedIn;
protected void Page_Load(object sender, EventArgs e)
{
isLoggedIn = Request.IsAuthenticated; // Is the user currently logged in
}
}
}
Here is my register page code behind:
namespace mysite
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (((MasterPage)Page.Master).isLoggedIn)
{
Response.Redirect("default.aspx");
}
}
}
}
I'm trying to make the isloggedIn accessible to all pages using that as a master page! I get errors like:
Error 2 The name 'isLoggedIn' does not exist in the current context
Error 3 'System.Web.UI.MasterPage' does not contain a definition for 'isLoggedIn' and no extension method 'isLoggedIn' accepting a first argument of type 'System.Web.UI.MasterPage' could be found (are you missing a using directive or an assembly reference?)
Any help appreciated.
add <%# MasterType VirtualPath="~/Main.master" %> to your page markup.
and your this.Master's type becomes AlphaPack.MasterPages.Main instead of System.Web.UI.MasterPage. So you will be able to access it without cast:
this.Master.IsLoggednIn
Currently you need do next:
((AlphaPack.MasterPages.Main)this.Master).isLoggednIn
And better - create a property. And hold data not in variable but in ViewState (read Control State vs. View State):
namespace AlphaPack.MasterPages
{
public partial class Main : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
this.IsLoggedIn = Request.IsAuthenticated;
}
public bool IsLoggedIn
{
get { return this.ViewState["isLoggedIn"] as bool? ?? false; }
set { this.ViewState["isLoggedIn"] = value; }
}
}
}
And what about code-behind. I recommend to use Web App project, not Web Site project (which is out-of-date)!
Next markup syntax is used. Web app:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="MyPage.aspx.cs" Inherits="MyNamespace.MyPage" MasterPageFile="~/MyMaster.master" Title="MyTitile" %>
and web site:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="MyPage.aspx.cs" Inherits="MyPage" MasterPageFile="~/MyMaster.master" Title="MyTitile" %>
if (((MasterPage)Page.Master).isLoggedIn)
Should be
if (((mysite.MasterPages.Main)Page.Master).isLoggedIn)
You cast Master to a MasterPage type (which is useless as it is already a MasterPage). But MasterPage doesn't contain the property isLoggedIn. That's why you can't access it.
So, just cast the Master property to the right type, in your case mysite.MasterPages.Main
The problem here is that your are declaring isLoggedIn within an inline code-block, so it will only be scoped to within that block.
You'll need to add it as a variable within the code-behind class or within <script runat="server"></script> tags, if adding the server-side code inline, i.e. (trimmed down for brevity):
<script runat="server">
public bool IsLoggedIn;
protected void Page_Load(object sender, EventArgs e)
{
IsLoggedIn = Request.IsAuthenticated;
}
</script>
You could then access the master page in subpages like so:
<%
if (((MasterPage)Page.Master).IsLoggedIn)
{
}
%>
However, I'm not sure that this is the best way to achieve what you want. I would probably take that logic out of the master page and stick it in a purpose built authentication class or service.
Usually one would store such Global 'states' inside a session variable. Are passing it around as a query string parameter?
And why are you not putting the code in the code behind?
Edit 1:
Just move this logic:
Response.Redirect("default.aspx");
directly into your masterpage:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated) // Is the user currently logged in
{
Response.Redirect("default.aspx");
}
}
If this is the default behaviour you want for all pages that will be using this Master Page.
Edit 2:
you said in a comment :
and how would i go about accessing the
variable on other pages?
There are 3 ways I can think of:
Query String (Per Page Request)
ViewState (Per Page)
Session Variable (Available Globally)
I have a menu of report links in my master page. I need to append an ID to the end of each whenever the user changes a value on the child page. What's a good way to accomplish this?
UPDATE: I should have mentioned that the child update is happening inside an UpdatePanel, meaning the master page is not reloaded when the change happens.
A MasterPage is really a child control of the page which it controls. You can control a MasterPage like any other control on your page (almost). All you need to do is get a reference to it.
You add a property to the code of your MasterPage, so its code may look something like this:
public partial class _default : System.Web.UI.MasterPage
{
protected string m_myString = string.Empty;
public string myString
{
get { return m_myString; }
set { m_myString = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
Then you have to cast the this.Master property to your MasterPage
public partial class index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Cast here to get access to your MasterPage
_default x = (_default)this.Master;
x.myString = "foo";
}
}
In response to your UPDATE:
The updated panel could write the ID to a hidden field and the menu events could look for that hidden fields in Request.Form["fieldName"].
Note that you shouldn't fieldName.Text because ASP.NET does a bad job of returning the right value for fields that have been AJAXed.