asp.net Disable master page menu - asp.net

Im working with asp.net and c#.
I have a master page and many aspx pages that use it.
The master page has a menu defined which is inside an unordered list(html).
I want to be able to disable the menu from the master page, from one of the aspx pages(lets call it page1), when the page1 loads.
<ul class="menu" id="menu" runat ="server">
<li>
Mant
<ul>
<li>Table</li>
</ul>
</li>
</ul>
How can I do that?
Thanks.

If you want to disable list from master page, then you can use this code in master page's Load event.
protected void Page_Load(object sender, EventArgs e)
{
if(ContentPlaceHolder1.Page.GetType().Name=="webform1_aspx")
{
ContentPlaceHolder1.Page.ClientScript.RegisterStartupScript(GetType(), "key", "javascript: document.getElementById('menu').style.visibility = 'hidden';", true);
}
}
If you want to use it in content page's load event then use this
ClientScript.RegisterStartupScript(GetType(), "key", "javascript: document.getElementById('menu').style.visibility = 'hidden';",true);
And menu is like this.
<ul id="listMenu" runat="server">
<li></li>
</ul>

You can access from content page like this :
MasterPagename ms = Master as MasterPagename ;
ms.NavigatorMenu.Items[0].disabled = true;

I think you can use content place holders:
Ex Master Page:
Add:
<asp:contentplaceholder id="Menu" runat="server">
<!-- Menu here -->
</asp:contentplaceholder>
In Content Pages(Page1 in your example) where you dont want to show menu add following tag and remove this from all content pages where you want menu to show:
<asp:Content ID="menuContent1" ContentPlaceHolderID="Menu" Runat="Server">
</asp:Content>

To find menu items in content page and disable it on pageload()
protected void Page_Load(object sender, EventArgs e)
{
Menu mainMenu = (Menu)Page.Master.FindControl("NavigationMenu");
foreach (MenuItem m in mainMenu.Items)
{
m.Enabled = false;
}
}

Related

how to avoid inline code in .aspx .ascx

I have a usercontrol (.ascx) like this:
<% if (HasAccessMediaPlans) { iPortletCounter++; %>
<div class="orange-portlet-box">
<div class="HomeModulePortletTitle">Plans</div>
<p>Create // Edit // Review</p>
</div>
<div style="clear: both;"></div>
<% } %>
where HasAccessMediaPlans is a variable defined in user control's code behind(.ascx.cs) and it's assigned in page load.
protected Boolean HasAccessMediaPlans = false;
protected void Page_Load(object sender, EventArgs e) {
HasAccessMediaPlans = SessionState.CurrentUser.HasModuleAccess(MediaString + " Plans");
}
My question is: how can I avoid inline server code embeded in <% %> at my usercontrol markup(.ascx) ?
You can wrap this piece of code with a server side container control (say <div id="wrapper" runat="server">) and on the server side assign its visibility properties in the wanted manner.
This avoids littering your .aspx/.ascx files with code and keeps code in the code-behind file.
<div class="orange-portlet-box" id="dvBox" runat="server">
<div class="HomeModulePortletTitle">
<a id="aLink">Plans</a>
</div>
<p>Create // Edit // Review</p>
</div>
<div style="clear: both;"></div>
In code behind
Boolean HasAccessMediaPlans = false;
protected void Page_Load(object sender, EventArgs e)
{
HasAccessMediaPlans = SessionState.CurrentUser.HasModuleAccess(MediaString + "Plans");
dvBox.Visible = HasAccessMediaPlans;
aLink.HREF = RootPath + "MediaPlanning/Default.aspx";
}

FindControl results in null reference

I have anchor tags like this
<div id="menu_container">
<ul id="nav-bar">
<li>Home</li>
<li><a href="Account.aspx" runat="server" id="menu_item_account" >Account</a></li>
<li>Servers</li>
<li>Statistics</li>
<li>Tutorials</li>
<li>Contact us</li>
<div id="login_registration_container">
Sign in / Register
</div>
</ul>
</div>
I want to change the CSS class for menu_item_default this way:
WebControl wc = (WebControl)FindControl("#menu_item_default");
wc.Attributes.Add("class", "value");
error: null reference exception
How can this be done?
You shouldn't use '#' symbol in the FindControl argument:
WebControl wc = (WebControl)FindControl("menu_item_default");
Using a MasterPage and the element is in a ContentPlaceholder:
If so then you must retrieve the ContentPlaceholder first, and from it retrive the element you want.
If your page has the following Content-area for example:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
Then you would do the following (error handling omitted):
var mainCtrl = Master.FindControl("MainContent");
var anchor = (HtmlAnchor) mainCtrl.FindControl("menu_item_default");
anchor.Attributes.Add("class", "value");
Using a MasterPage and the element is in the MasterPage:
use:
var anchor = (HtmlAnchor) Master.FindControl("menu_item_default");
Is there a particular reason you are using a regular anchor tag? Why not use an ASP.Net LinkButton? That will make it much easier to reference in the code.
If the control is on the master page, try
Master.FindControl()

check for condition in site.master page

I have a site.master page in an asp application which contains a div menu and it looks like this.
<div id="menu">
<ul>
<li class="first">home</li>
<li>manager services</li>
<li>employee services</li>
<li>my projects</li>
</ul>
</div>
What i want is that the manager services portion should be visible only if a particular employee has his 'Is_Manager' field set to True in the database. For the rest this tag should be invisible. How do I achieve this?? How do i check for this contidion over here in this site.master page? please help.
Do it inside of the mark up. In the code behind on page load, set the Is_Manager flag and look it up from the database. Then, in the markup, do this:
<% if(Is_Manager){%>
<li>Manager Services</li>
<%}%>
Given what you've provided so far ...
in the cs file for the master:
protected bool IsVisible;
protected void Page_Load(object sender, EventArgs e){
IsVisible = (bool)Session["isVisible"];
}
in the aspx for the master page
<style>
.manager { visibility = <%= (IsVisible) ? "visible" : "hidden" %>;}
</style>
<div id="menu">
<ul>
<li class="first">home</li>
<li class="manager">manager services</li>
<li>employee services</li>
<li>my projects</li>
</ul>
</div>

change master page <a href link from content page

i have this on my master.page
<ul class="menu">
<li class="first" runat="server" id="Li2">
<a runat="server" id="A1" href="../NewEntry.aspx">Create a New Entry</a>
</li>
</ul>
when i go to content page ("NewEntry.aspx") i want the link name to be changed to "Update Entry"
<ul class="menu">
<li class="first" runat="server" id="Li2">
<a runat="server" id="A1" href="../UpdateEntry.aspx">Update Entry</a>
</li>
</ul>
any feedback?
Make the link an asp:Hyperlink. Then have the master page expose a function or property:
public void SetLink(string href, string text)
{
A1.NavigateURL = href;
A1.Text = text;
}
Call the function from the main page.
You can use a hyperlink control <asp:hyperlink> and set the url as well as the text values.
I would recommend handling this as a HyperLink control as others have mentioned. If for some reason you must handle this as a server-side HTML anchor, you can access it using the following code from your webform code-behind:
HtmlAnchor link = (HtmlAnchor)(this.Master).FindControl("A1");
link.InnerText = "Update Entry";
You can also define a content place holder where you have "Create a New Entry". Leave that as the default inside that place holder, and only in the content page set content for it to Update Entry.

ASP.NET: User control with access to the controls that it wraps

I have a bunch of occurrences of this kind of boilerplate code in my ASP.NET project.
<div class="inputfield">
<div class="tl">
<span class="tr"><!-- --></span>
<span class="ll"><!-- --></span>
<div class="lr">
<div class="cntnt">
<asp:TextBox .../>
</div>
</div>
</div>
</div>
As you may have guessed, everything in that snippet is pure boilerplate except for the innermost text field.
What is the best way to avoid such boilerplate in ASP.NET? In e.g. Django I would make a custom tag for it, as such:
{% boiler %}
<input ... />
{% endboiler %}
I was thinking that maybe I can create a user control, but all the tutorials on ASP.NET user controls that I've found are very simplistic and "self-closing", i.e. they are not aware of the contents of the tag. I need something along the lines of:
<Hello:MyControl>
<asp:TextBox .../>
</Hello>
So my question is the following: what's the best way to avoid the boilerplate?
You can use an ITemplate property. Thus, you can inject different content in different situations.
[PersistChildren(false), ParseChildren(true, "ContentTemplate")]
public partial class WebUserControl1 : System.Web.UI.UserControl
{
[System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate ContentTemplate { get; set; }
protected override void CreateChildControls()
{
if (this.ContentTemplate != null)
this.ContentTemplate.InstantiateIn(this);
base.CreateChildControls();
}
}
Put the asp:TextBox in your user control, along with the other html tags. Provide properties on your user control that match the properties of the text box, so that you would do something like this:
<Hello:MyControl ID="myControl" runat="server" Width="300px" MaxLength="30" />
and then the width and maxlength properties would just get transferred to the internal textbox.
You could also provide access to the textbox from the usercontrol and set all the properties in the code behind.
Create a class like this:
[PersistChildren(false), ParseChildren(true, "ContentTemplate")]
public class CustomContent:WebControl
{
[System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public ITemplate ContentTemplate { get; set; }
private PlaceHolder m_placeHolder;
protected override void CreateChildControls()
{
m_placeHolder = new PlaceHolder();
if (this.ContentTemplate != null)
this.ContentTemplate.InstantiateIn(m_placeHolder);
Controls.Add(m_placeHolder);
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write(#"<div class=""inputfield"">
<div class=""tl"">
<span class=""tr""><!-- --></span>
<span class=""ll""><!-- --></span>
<div class=""lr"">
<div class=""cntnt"">
");
base.RenderContents(writer);
writer.Write(#" </div>
</div>
</div>
</div>
");
}
}
This class isn't a "User Control" it's a "Server Control". You can do the same thing with a user control but you'll have issues with the designer. This will work in the designer.
And you can put markup like this in your ASPX:
<uc1:CustomContent runat="server" ID="content">
<asp:textbox runat="server"></asp:textbox>
</uc1:CustomContent>
don't forget the Register page declaration at the top of the aspx
<%# Register tagprefix="uc1" Assembly="Assembly where CustomContent is" Namespace="namespace where CustomContent is" %>
You can put whatever you want inside the uc1:CustomContent tags and it will render that boilerplate html around it. If you are curious about how ITemplate works, there are plenty of articles on msdn, etc.

Resources