Add class to ASP.NET MasterPage control - c#

This is the code in my MasterPage:
<li id="liABOUT" runat="server">ABOUT</li>
When I am on another page referencing the MasterPage I want to add a class to this li control, something like this. Cant get it to work. Using ASP.NET 4.5
Me.Master.FindControl("ContentPlaceHolderMaster").FindControl("LiAbout").Attributes.Add("class", "active")
VB.NET or C# Code would be fine

You can create a public property in your MasterPage :
public String LiAboutClass
{
get { return liABOUT.Attributes["class"]; }
set { liABOUT.Attributes["class"] = value; }
}
Access this property in your ContentPage:
var siteMaster = (SiteMaster)this.Master;
if (siteMaster != null) siteMaster.LiAboutClass = "active";
Edit: Also you can use MasterType. it allows you to access the MasterTypes properties directly.

This works for me. I first converted it to HtmlGenericControl and then added attribute.
(Master.FindControl("liABOUT") as HtmlGenericControl).Attributes.Add("class", "active");

This worked....
' Get reference to control located on master page
Dim lb As HtmlGenericControl = Page.Master.FindControl("liABOUT")
lb.Attributes.Add("class", "active")

Related

Cache Controls loaded at Runtime

My question is similar to Access to PartialCachingControl.CachedControl before Add it but since i cannot add the control to page before setting control attributes im still having problems
I have a UserControl with a public property called "Content" which i would like to cache. On the UserControl ive added:
<%# OutputCache Duration="60" VaryByParam="none" %>
Before adding the Cache Attribute i used to load the controls as followed
public static Control DocumentWidget (System.Web.UI.Page currentPage, Comito.LokalPortalen.Domain.Entity.CMS.Content.Content content)
{
Comito.LokalPortalen.FrontEndShared.Controls.Document.Widget documentWidget = (FrontEndShared.Controls.Document.Widget)currentPage.LoadControl("/FrontEndShared/Controls/Document/Widget.ascx");
if (documentWidget != null)
{
documentWidget.Content = content;
return documentWidget;
}
return null;
}
I would now like to do something like :
PartialCachingControl documentWidget = (PartialCachingControl)currentPage.LoadControl("/FrontEndShared/Controls/Document/Widget.ascx");
if (documentWidget != null)
{
System.Reflection.PropertyInfo cmsContent = documentWidget.GetType().GetProperty("Content");
documentWidget.Content = content;
return documentWidget;
}
Which fails with "PartialCachingControl doesnt contain a definition for "Content"
or like the solution supposed in Access to PartialCachingControl.CachedControl before Add it but since i cant add the control before setting attributes this doesnt Work.
Any solution

How call GetWebResourceUrl() when Page is null ?

I built custom ASP.NET control and it's working fine when I add it manually (drag and drop) or by code to controls in markup.
The custom control, MsgBox, had resources like JavaScript, CSS and images embedded in and the problem appeared when I tried to Render the control in class to return its HTML code, the Page instance is null and the "GetWebResourceUrl" needs it:
Page.ClientScript.GetWebResourceUrl(.....)
is there any way to get the resourceurl ? Here is my render code:
protected override void RenderContents(HtmlTextWriter writer)
{
using (PlaceHolder plh = new PlaceHolder())
{
if (Page != null)
{
if (DesignMode || Page.Header == null)
RegisterCSSInclude(plh);
}
HtmlGenericControl container = new HtmlGenericControl("div");
container.EnableViewState = false;
container.InnerHtml = "Control html code";
plh.Controls.Add(container);
plh.RenderControl(writer);
}
}
RegisterCSSInclude is method to register my css files:
private void RegisterCSSInclude(Control target)
{
// CSS
bool linkIncluded = false;
foreach (Control c in target.Controls)
{
if (c.ID == "MsgBxStyle")
{
linkIncluded = true;
}
}
if (!linkIncluded)
{
HtmlGenericControl globalCsslink = new HtmlGenericControl("link");
globalCsslink.ID = "MsgBxGStyle";
globalCsslink.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl(typeof(MessageBoxCtrl), "MessageBox.MsgBxStyles.WeDevMsgBox.css"));
globalCsslink.Attributes.Add("type", "text/css");
globalCsslink.Attributes.Add("rel", "stylesheet");
globalCsslink.EnableViewState = false;
target.Controls.Add(globalCsslink);
HtmlGenericControl csslink = new HtmlGenericControl("link");
csslink.ID = "MsgBxStyle";
csslink.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl(typeof(MessageBoxCtrl), "MessageBox.MsgBxStyles." + Style.ToString().ToLower() + ".css"));
csslink.Attributes.Add("type", "text/css");
csslink.Attributes.Add("rel", "stylesheet");
csslink.EnableViewState = false;
target.Controls.Add(csslink);
}
}
Update:
PS: I'm tring to use control in generic handler (ashx) where I call ShowMsgBox method which is a method in a class and not in a page or user control.
ShowMsgBox method should create an instance of MsgBox control and render it then return the html code to ashx class :
var htmlCode = MyClass.ShowMsgBox("myMsg");
context.Response.write(htmlCode);
I built a custom ASP.NET control ...
I'm tring to use control in generic handler (ashx) ... not in a page or user control.
A Page is a handler. You want to use a convenience provided by the Page class, but you don't want to inherit from Page. The niceties of Page, such as ClientScript, expect a Page from which to get various information.
You can provide a dummy Page object to your control by setting the Page property of your custom Control:
this.Page = new Page();
...then you will need to set various properties (assuming they are public) which are expected by ClientScriptManager.GetWebResourceUrl():
this.Page.Foo = "bar";
then you can call:
this.Page.ClientScript.GetWebResourceUrl(...);
If this is the specific class that inherits from WebControl page shouldn't be null. If its another class that you are rendering as part of a hierarchy you can add a parameter of type Page and pass the reference of the current page to it.

ASP.NET How to access a deeply nested user control on the parent page

I have a login control and at is nested 2 deep in a header control
i.e Page --> Header Control --> Login Control. I cannot get a reference to the control on the page using FindControl. I want to be able to set the visible property of the control like
if (_loginControl != null)
_loginControl.Visible = false;
I ended up using a recursive FindControl method to find the nested control.
public static Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}
Are you needing to disable/hide the User Control from the ASP.NET page it resides on (or does the User Control exist on a master page, say)? If it's in the same page, then in your ASP.NET page's code-behind you'd do:
MyUserControlsID.Visible = false
Where MyUserControl is the ID of your User Control. To determine the ID of your User Control look at the markup of your .aspx page and you will see something like this:
<uc1:UserControlName ID="MyUserControlsID" runat="server" ... />
Happy Programming!
A good way would be to use:
Page.FindControl()
if that yields null, the control is not there.
Try calling this.FindControl("_loginControl") or this.Page.FindControl("_loginControl").
See MSDN for method details:
http://msdn.microsoft.com/en-us/library/system.web.ui.control.findcontrol.aspx
The login control, if it's registered in the markup, will also be an instance member of your codebehind page; you can refer to it from the codebehind class as if it were a normal member, using the same name you provided as the ID (I do recommend using codebehinds for most logic, instead of inlining code in the markup, BTW).
You can also use the FindControl() method of your page, which will search its control subtree for a control with a given ID. That takes longer, so I would recommend the first option unless the logic control is added dynamically and you don't always know it's there.
private List<Control> GetAllNestedUserControl(Control ph)
{
List<Control> Get = new List<Control>();
foreach (var control in ph.Controls)
{
if (control is UserControl)
{
UserControl uc = control as UserControl;
if (uc.HasControls())
{
Get = GetAllNestedUserControl(uc);
}
}
else
{
Control c = (Control)control;
if (!(control is LiteralControl))
{
Get.Add(c);
}
}
}
return Get;
}
just call this code from you any parent page and then get any control by the following code
List<Control> Get = GetAllNestedUserControl(ph);
Label l = (Label)Get.Find(o => o.ID == "lblusername");
l.Text = "changed from master";

Change panel "visible" property on MasterPage from Child pages

I want to show some panel with a label, both located on a MasterPage, from inside it's child pages.. I already did the coding on the MasterPage:
public class MyMaster : MasterPage
{
public void ShowPanel(string pMessage)
{
labelInside.Text = pMessage;
myPanel.visible = true;
}
}
Then I make the calls from child pages:
public void ShowPanel(string pMessage)
{
MyMaster masterPage = this.Master as MyMaster;
masterPage.ShowPanel(pMessage);
}
This "works" ok, but it won't show nothing, since I need the page to be "refreshed" in an "ajax-way" like an UpdatePanel, which I can't use because the Trigger is in another page, right?
I really need this to work.. even if you have another completely different way to do this, I would appreciate.
You must place your panel inside an UpdatePanel(UpdateMode conditional) and in ShowPanel call its Update method.
Have you considered having the masterpage just have a placeholder for the label, but having each child page put its own content label inside that placeholder, which it would then have full control over?
you can subClass your page, and expose a property say.. MyPage.FooVisible
than in your masterPage, you can:
myPage = this.Page as MyPage
if (myPage != null) myPage.FooVisble = false;
in your page you can handle that any way you like,
FooVisible {
set { SomeElement.Visible = value; }
}
pseudo code of course :)

How to add a css reference within a server control?

I've built a custom server control that uses custom CSS. The problem that I have is that I have to set a reference to the css file on each page I use the control.
Can I set this reference inside the control ? So that I could just add the control and not worry about the reference.
You need to follow the below steps to add the css/javascript/image in the web control itself.
Modify the AssemblyInfo.cs file, to add the web resource
[assembly: System.Web.UI.WebResource("CustomControls.Styles.GridStyles.css", "text/css"), PerformSubstitution = true)]
Adding the required files(css/javascript/images) to the custom server control solution. Note that we can add folders in the solution and just add separate it using '.'(dot)
More importantly, we should change the BuildAction Property from Content to Embedded Resource of the newly added css/javascript/image files.
Further we should load the stored resources from the DLL. Best event for this would be OnPreRender
Below is the sample code rendering css
protected override void OnPreRender(EventArgs e)
{
bool linkIncluded = false;
foreach (Control c in Page.Header.Controls)
{
if (c.ID == "GridStyle")
{
linkIncluded = true;
}
}
if (!linkIncluded)
{
HtmlGenericControl csslink = new HtmlGenericControl("link");
csslink.ID = "GridStyle";
csslink.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl(this.GetType(), "CustomControls.Styles.GridStyles.css"));
csslink.Attributes.Add("type", "text/css");
csslink.Attributes.Add("rel", "stylesheet");
Page.Header.Controls.Add(csslink);
}
}
Similarly for Adding javascript
protected override void OnPreRender(EventArgs e)
{
string resourceName = "CustomControls.GridViewScript.js";
ClientScriptManager cs = this.Page.ClientScript;
cs.RegisterClientScriptResource(this.GetType(), resourceName);
}
Similarly using the Added Image in CSS file. Use the below code
background: url('<%=WebResource("CustomControls.Styles.Cross.png")%>') no-repeat 95% 50%;
Thanks.
Here what I use to add css reference to Page programmatically :
HtmlLink link = new HtmlLink();
link.Href = relativePath;
link.Attributes["type"] = "text/css";
link.Attributes["rel"] = "stylesheet";
Page.Header.Controls.Add(link);
Maybe you should add some code to check if the css file added to the header control.
If you want build webcontrol, that will be reusable and in one assembly with css, js and other resources, than you can use WebResources
Working with Web Resources in ASP.NET 2.0
You could do it with a ScriptManager - and this will also help you embed the stylesheet in the custom control library's DLL.
Or you could just reference the CSS from your master page. Unless you're packging a custom control library to sell etc, ScriptManager is a LOT of extra effort vs the Master Page solution
I would think you could add Canavar's code to a base class that would be included with all the classes that need it.
public class myclass : BaseClass
{
var customCSS = customcss();
Page.Header.Controls.Add(customCSS); }
and your baseclass:
public class BaseClass : Page
{
public HtnlLink customcss(){
HtmlLink link = new HtmlLink();
link.Href = relativePath;
link.Attributes["type"] = "text/css";
link.Attributes["rel"] = "stylesheet";
return link;
}
}
or you could go down the route of
myObject.Attributes.Add("style","width:10px; height:100px;");
or
myObject.Attributes.Add("style",customStyle(););
where this is in your baseclass
public String customStyle()
{
return "width:10px; height:20px;";
}
and customstyle would be a function like so:
But I would assume that you use CSS for the rest of your site, so maybe a style could just be added to your stylesheet that you use on all pages through this method you could use the below code:
myObject.Attributes.Add("class","customControl");
This will then reference the correct CSS style from your main, always included stylesheet.
Unless I am missing something here....

Categories

Resources