Can a Web User Control (.Ascx) Use a CSS File for Styling

Can a Web User Control (.ascx) use a CSS file for styling?

The CSS is associated to the page, and not the control specifically. But you can use the CSS in the control when the page has referenced it.

User Control with external CSS file

As I mentioned in my comments I didn't want to use <%= %> blocks. But I didn't want to assign URL of CSS file in code-behind either, so I found a compromise. I declare <link> tag with runat="server" attribute and ASP.NET - style href:

<link rel="stylesheet" type="text/css" runat="server" id="xlinkCSS" href="~/MyStyle.CSS" />

and then in code-behind simple resolve that link

xlinkCSS.Attributes("href") = ResolveUrl(xlinkCSS.Attributes("href"))

Using this approach ultimately I can create a function that accepts page as a parameter, loops thru all "link" tags, resolving their URLs.

Can a user control come with its own CSS styles embedded in the user control?

Javascript tags can be placed just about anywhere. The head seams like the logical place to put it but some people recommend placing it at the very bottom just before </body>. This way the content of your page should load faster and might improve SEO.

Stylesheets should definitely be placed in the <head> as it is a W3C recommendation.
When using stylesheets take Tim's advice to sneak them into the head, or better yet just use an external .css file.

How to make user controls know about css classes in ASP.NET

Here's what I did:

<link rel="Stylesheet" type="text/css" href="Stylesheet.css" id="style" runat="server" visible="false" />

It fools Visual Studio into thinking you've added a stylesheet to the page but it doesn't get rendered.


Here's an even more concise way to do this with multiple references;

<% if (false) { %>
<link rel="Stylesheet" type="text/css" href="Stylesheet.css" />
<script type="text/javascript" src="js/jquery-1.2.6.js" />
<% } %>

As seen in this blog post from Phil Haack.

Adding styles and scripts to ASP.NET web controls (ascx) without repeating inclusion directives

One thought: wouldn't it be possible to use ClientScriptManager.RegisterClientScriptBlock to inject the css-file import?

Something like(not tested):

if(! Page.ClientScript.IsClientScriptBlockRegistered("MyWebControl.ascx.css"))
{
Page.ClientScript.RegisterClientScriptBlock(this.getType(),"MyWebControl.ascx.css",@"<style type=""text/css"" src=""MyWebControl.ascx.css""></style>");
}

Edited to change RegisterStartupScript to RegisterClientScriptBlock

According to your edits:

  • RegisterStartupScript(type, key, script)
  • RegisterClientScriptBlock(type, key, script)

The difference between these two methods is where each one emits the script block. RegisterClientScriptBlock() emits the script block at the beginning of the Web Form (right after the tag), while RegisterStartupScript() emits the script block at the end of the Web Form (right before the tag).

To better understand why there are two different methods for emitting client-side script, realize that client-side script can be partitioned into two classes: code that is designed to run immediately when the page is loaded, and code that is designed to run when some client-side event occurs. A common example of code that is designed to run when the page is loaded is client-side code designed to set the focus to a textbox. For example, when you visit Google, a small bit of client-side code is executed when the page is loaded to automatically set the focus to the search textbox.

http://msdn.microsoft.com/en-us/library/aa478975.aspx#aspnet-injectclientsidesc_topic2

Edit: from your comments i'm assuming that it unfortuately does not work this way. Have a look at following links:

  • http://forums.asp.net/t/557140.aspx/1?CSS+stylesheet+in+ascx+file/?post=2692177
  • http://nathanaeljones.com/146/referencing-stylesheets-scripts-from-content-pages/

There might be some working approaches

As a hint, you could create the HtmlLink programmatically in Page_Init-Handler of your UserControl:

Dim objLink As New HtmlLink();
objLink.ID = "MyWebControlascxcss";
objLink.Attributes("rel") = "stylesheet";
objLink.Attributes("type") = "text/css";
objLink.Href ="~/filname.css";
Page.Header.Controls.Add(objLink);

You should remember to check first with a recursive function if the link was already added to Page.Header.Controls-Collection.

ASP.NET: Create new CSS class programmatically from User Control?

If the CSS is defined in your .ASCX file, it should be rendered every time, postback or not. Unless the control itself is set to Visible="false".

One workaround is to define the CSS code within an asp:Literal block on your control. Your control can then expose a public function that simply returns the contents of that literal to the caller. If a host is going to make your control invisible, they can grab the CSS code using that public function, and place it within the head section of the page. In that way, the CSS definition should always be there, regardless of the Visibility setting of the control.

In the larger scheme of things, Adam is correct: it's better to keep your CSS code in .CSS files wherever possible.

Where to put CSS rules in ASCX custom control?

If the control you are creating is in a separate assembly, you can embed the CSS files inside the assembly to make it reusable and create a direct link to these files from your control, then in your control you will register them to be rendered as link tags in your page

Note: Remember that you need to mark the CSS file in your assembly as an Embedded Resource

Just select your file | then proeprties and change its Build Action property and set it to: embedded Resource

Sample Image

In the following code:

  • AjaxEnabled.Web.UI represents the namespace of your assembly

  • DefaultStyle.css represents the embedded CSS file name

The following code sample shows the steps needed: (in your custom server control)

[assembly: WebResource("AjaxEnabled.Web.UI.DefaultStyle.css", "text/css")]

protected override void OnInit(EventArgs e)
{
base.OnInit(e);

if (this.Page.Header != null)
{
if (!this.Page.ClientScript.IsClientScriptBlockRegistered("defaultCss"))
{
var link = new HtmlLink();

link.Href = this.Page.ClientScript.GetWebResourceUrl(
typeof(YourControlType),
"AjaxEnabled.Web.UI.DefaultStyle.css"
);
link.Attributes.Add("rel", "stylesheet");
link.Attributes.Add("type", "text/css");

this.Page.Header.Controls.Add(link);
this.Page.ClientScript.RegisterClientScriptBlock(
typeof(Page),
"defaultCss",
string.Empty
);
}
}
}

You need to add an instance of the ScriptManager control in your page containing your custom controls

<asp:ScriptManager runat="server" ID="sm"/>

And in your ASPX page you need to mark the header section as a server control

<head runat="server">

The following code:

link.Href = this.Page.ClientScript.GetWebResourceUrl(
typeof(YourControlType),
"AjaxEnabled.Web.UI.DefaultStyle.css");

Renders a link directly to the CSS file embedded in the assembly


This condition:

if (!this.Page.ClientScript.IsClientScriptBlockRegistered("defaultCss"))
...
this.Page.ClientScript.RegisterClientScriptBlock(
typeof(Page),
"defaultCss",
string.Empty
);

ensures that the CSS is rendered only once in the page, even if you drop more than one instances of your control

ASP.NET User Control - Change Style of Div based on Color Scheme Choice

usercontrols inherit the css from the aspx or site.master pages so what you could do is in each css either add

#divUserEntry{color:#fff;}

or set a css class and then your div

<div id="divUserEntry" runat="server" class="usercontrol">

but still in each css they have to add

.usercontrol{color:#fff;}

asp.net mvc stand alone ascx control how do i link (css and js) most efficiently

I am adding my own answer, it might be that my question was not clear enough. In any case if someone needs a solution this is where I am at the moment:


This is the bottom section of the partial (Control)

<%--
///-----------------------------------------------------------------------
/// <summary>
/// <title>Java Scripts Section</title>
/// Contains all links to java script files that are used by this
/// partial.
///
/// If the partial is part of a viewpage, only the partial's scripts
/// should be downloaded. (It was called using Ajax)
///
/// In the case that the partial acts as a stand alone control it needs
/// to fetch other scripts that are preloaded by the application.
/// (For example jQuery)
///
/// This is achived by identifying that the partial was not called
/// via Ajax in this case the list of Java Script files that have
/// been included is added to the HTML that then fetches them from
/// the server.
/// <ToDo>
/// A. Need to join and minify scripts to improve performance.
/// B. Consider identifing the Ajax call in the controller:
/// request.IsAjaxRequest().
/// </ToDo>
/// </summary>
///-----------------------------------------------------------------------
--%>
<%
string areaRoot = "~/Areas/Manufactor/";
string areaJsRoot = areaRoot + "JQuery/";

string dataLayer = areaJsRoot + "manufactorAjax.js";
string javaScript = areaJsRoot + "vucManufactorDetails.js";
%>
<% if (HttpContext.Current.Request.Headers.Get("X-Requested-With") != "XMLHttpRequest") { %>
<!-- #Include virtual="~/Include/GenericScripts.inc" -->

<script type="text/javascript" src="<%= ResolveUrl(dataLayer)%>">
</script>
<% }; %>

<script type="text/javascript" src="<%= ResolveUrl(javaScript)%>">
</script>
<%--
///-----------------------------------------------------------------------
/// <end>
/// This ends the ManufactorDetails.ascx file.
/// </end>
///-----------------------------------------------------------------------
--%>

This is the content of the include file:

<%--
///-----------------------------------------------------------------------
/// <summary>
/// <link>System generic Scripts</link>
/// The system generic scripts used to manage controls in the system.
/// </summary>
///-----------------------------------------------------------------------
--%>

<%
string jsRoot = "~/Scripts/";

string jqueryLink = jsRoot + "jquery-1.4.1.min.js";
string jqueryUI = jsRoot + "jquery-ui-1.8.4.custom.min.js";
string jqueryCorner = jsRoot + "jquery.corner.js";
string microsoftAjax = jsRoot + "microsoftAjax.js";
string microsoftMvcAjax = jsRoot + "microsoftMvcAjax.js";
string dataProvider = jsRoot + "dataProvider.js";
%>

<script type="text/javascript" src="<%= ResolveUrl(jqueryLink)%>">
</script>

<script type="text/javascript" src="<%= ResolveUrl(jqueryUI)%>">
</script>

<script type="text/javascript" src="<%= ResolveUrl(jqueryCorner)%>">
</script>

<script type="text/javascript" src="<%= ResolveUrl(microsoftAjax)%>">
</script>

<script type="text/javascript" src="<%= ResolveUrl(microsoftMvcAjax)%>">
</script>

<script type="text/javascript" src="<%= ResolveUrl(dataProvider)%>">
</script>

<%--
///-----------------------------------------------------------------------
/// End of GenericScript.inc
///-----------------------------------------------------------------------
--%>

I have applied similar logic for css files at the top of the partial.

Note:

The include file is always loaded.
In the case of the partial - that is part of the web application it is not processed.

Be happy and enjoy life, Julian



Related Topics



Leave a reply



Submit