如何把样式表控制在ASP.NET主题与StylePlaceHolder和样式的控制 [英] How to take control of style sheets in ASP.NET Themes with the StylePlaceHolder and Style control

查看:187
本文介绍了如何把样式表控制在ASP.NET主题与StylePlaceHolder和样式的控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:这变成了一个博客帖子,提供更新的链接和code,在我的博客:<一href=\"https://egilhansen.com/2008/12/01/how-to-take-control-of-style-sheets-in-asp-net-themes-with-the-styleplaceholder-and-style-control/\" rel=\"nofollow\">https://egilhansen.com/2008/12/01/how-to-take-control-of-style-sheets-in-asp-net-themes-with-the-styleplaceholder-and-style-control/

Update: This turned into a blog post, with updated links and code, over at my blog: https://egilhansen.com/2008/12/01/how-to-take-control-of-style-sheets-in-asp-net-themes-with-the-styleplaceholder-and-style-control/

问题是pretty简单。当使用ASP.NET主题你没有在样式表中是如何呈现的页面多说了。

The problem is pretty simple. When using ASP.NET Themes you do not have much say in how your style sheets are rendered to the page.

渲染引擎将所有的样式表,你有你的主题按字母顺序排列的文件夹,使用的&lt;链接HREF =...表示法

The render engine adds all the style sheets you have in your themes folder in alphabetic order, using the <link href="..." notation.

我们都知道样式表的顺序很重要,幸运的是asp.nets缺点可以通过prefixing用样式表来规避01,02,...,99,从而迫使你想要的顺序(看到生锈的Swayne 博客文章在技术上了解详情)。

We all know the order of the style sheets are important, luckily asp.nets shortcomings can be circumvented by prefixing the style sheets with 01, 02, ... , 99, and thus forcing the order you want (see Rusty Swayne blog post on the technique for more information).

如果您使用重置样式表,我强烈建议这一点尤其重要;这使得它更容易在不同的浏览器一致的形式风格的网站(看看的复位从埃里克迈耶重装上阵)。

This is especially important if you use a reset style sheet, which I highly recommend; it makes it much easier to style a site in a consistent form across browsers (take a look at Reset Reloaded from Eric Meyer).

您还错过的可能性,以指定媒体类型(例如屏幕,打印,投影,盲文,语音)。如果你preFER使用@import方法,包括样式表,你也冷落了。

You also miss out of the possibility to specify a media type (e.g. screen, print, projection, braille, speech). And if you prefer to include style sheets using the @import method, you are also left out in the cold.

另一个失踪的选择是有条件的评论,如果您使用的,即-fix.css样式表这是非常有用的。

Another missing option is Conditional Comment, which is especially useful if you use an "ie-fix.css" style sheet.

在我解释StylePlaceholder和样式的控制如何解决上述问题,信贷,信贷是因为,我的解决方案是由<一个启发href=\"http://www.dentaku.com/2007/01/take-control-over-stylesheet-order-and-media-when-using-asp-net-2-0-themes.aspx\"相对=nofollow>每齐默尔曼的博客文章关于这个问题的。

Before I explain how the StylePlaceholder and Style control resolve the above issues, credit where credit is due, my solution is inspired by Per Zimmerman’s blog post on the subject.

该StylePlaceHolder控件放置在你的母版页或页面的页眉部分。它可以承载一个或多个样式的控制,并通过删除默认渲染引擎添加的风格,并加入了自己的(它只会删除当前活动的主题添加样式)。

The StylePlaceHolder control is placed in the header section of your master page or page. It can host one or more Style controls, and will remove styles added by the render engine by default, and add its own (it will only remove styles added from the current active theme).

样式控制可以在两者之间它的开幕,并通过其CssUrl财产结束标记和参照外部样式表文件中同时主机内嵌样式。与其他属性,你如何控制样式表它呈现的网页。

The Style control can both host inline styles in-between it’s opening and closing tags and a reference to a external style sheet file through its CssUrl property. With other properties you control how the style sheet it renders to the page.

让我告诉一个例子。考虑与母版页简单的网站项目,并与三个样式表一个主题 - 01reset.css,02style.css,99iefix.cs。注:我一直在使用prefixing技术前面所述将它们命名,因为它使一个更好的设计时体验。此外,自定义控件的标签preFIX是驴。

Let me show an example. Consider a simple web site project with a master page and a theme with three style sheets – 01reset.css, 02style.css, 99iefix.cs. Note: I have named them using prefixing technique described earlier, as it makes for a better design time experience. Also, the tag prefix of the custom controls is "ass:".

在母版页的页眉部分,添加:

In the master page’s header section, add:

<ass:StylePlaceHolder ID="StylePlaceHolder1" runat="server" SkinID="ThemeStyles" />

在你的主题目录中,添加一个皮肤文件(例如Styles.skin),并添加以下内容:

In your theme directory, add a skin file (e.g. Styles.skin) and add the following content:

<ass:StylePlaceHolder1runat="server" SkinId="ThemeStyles">
    <ass:Style CssUrl="~/App_Themes/Default/01reset.css" />
    <ass:Style CssUrl="~/App_Themes/Default/02style.css" />
    <ass:Style CssUrl="~/App_Themes/Default/99iefix.css" ConditionCommentExpression="[if IE]" />
</ass:StylePlaceHolder1>

这基本上是它。有对可用于控制呈现样式控制多种性质,但是这是基本设置。考虑到这地方,你可以轻松地添加另一个主题,并更换所有样式,因为你只需要包含不同的皮肤文件。

That is basically it. There are a more properties on the Style control that can be used to control the rendering, but this is the basic setup. With that in place, you can easily add another theme and replace all the styles, since you only need to include a different skin file.

现在到code,使这一切发生。我必须承认,在设计时体验有一些怪癖。这可能是由于这样的事实,我不是以书面自定义控件(事实上,这两个是我第一次尝试)很精通,所以我很希望在接下来的输入。在当前WCAB / WCSF基于项目我发展,我看到这样的错误在Visual Studios的设计视图,我不知道为什么。该网站汇集,一切工作网上。

Now to the code that makes it all happen. I must admit that the design time experience have some quirks. It is probably due to the fact that I am not very proficient in writing custom controls (in fact, these two are my first attempts), so I would very much like input on the following. In a current WCAB/WCSF based project I am developing, I am seeing errors like this in Visual Studios design view, and I have no idea why. The site compiles and everything works online.

以下是code为StylePlaceHolder控制:

The following is the code for the StylePlaceHolder control:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;

[assembly: TagPrefix("Assimilated.Extensions.Web.Controls", "ass")]
namespace Assimilated.WebControls.Stylesheet
{
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [DefaultProperty("SkinID")]
    [ToolboxData("<{0}:StylePlaceHolder runat=\"server\" SkinID=\"ThemeStyles\"></{0}:StylePlaceHolder>")]
    [ParseChildren(true, "Styles")]
    [Themeable(true)]
    [PersistChildren(false)]
    public class StylePlaceHolder : Control
    {
        private List<Style> _styles;

        [Browsable(true)]
        [Category("Behavior")]
        [DefaultValue("ThemeStyles")]
        public override string SkinID { get; set; }

        [Browsable(false)]
        public List<Style> Styles
        {
            get
            {
                if (_styles == null)
                    _styles = new List<Style>();
                return _styles;
            }
        }

        protected override void CreateChildControls()
        {
            if (_styles == null)
                return;

            // add child controls
            Styles.ForEach(Controls.Add);
        }

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

            // get notified when page has finished its load stage
            Page.LoadComplete += Page_LoadComplete;
        }

        void Page_LoadComplete(object sender, EventArgs e)
        {
            // only remove if the page is actually using themes
            if (!string.IsNullOrEmpty(Page.StyleSheetTheme) || !string.IsNullOrEmpty(Page.Theme))
            {
                // Make sure only to remove style sheets from the added by
                // the runtime form the current theme.
                var themePath = string.Format("~/App_Themes/{0}",
                                              !string.IsNullOrEmpty(Page.StyleSheetTheme)
                                                  ? Page.StyleSheetTheme
                                                  : Page.Theme);

                // find all existing stylesheets in header
                var removeCandidate = Page.Header.Controls.OfType<HtmlLink>()
                    .Where(link => link.Href.StartsWith(themePath)).ToList();

                // remove the automatically added style sheets
                removeCandidate.ForEach(Page.Header.Controls.Remove);
            }
        }

        protected override void AddParsedSubObject(object obj)
        {
            // only add Style controls
            if (obj is Style)
                base.AddParsedSubObject(obj);
        }

    }
}

而code的风格控制:

And the code for the Style control:

using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;

[assembly: TagPrefix("Assimilated.Extensions.Web.Controls", "ass")]
namespace Assimilated.WebControls.Stylesheet
{
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [DefaultProperty("CssUrl")]
    [ParseChildren(true, "InlineStyle")]
    [PersistChildren(false)]
    [ToolboxData("<{0}:Style runat=\"server\"></{0}:Style>")]
    [Themeable(true)]
    public class Style : Control
    {
        public Style()
        {
            // set default value... for some reason the DefaultValue attribute do
            // not set this as I would have expected.
            TargetMedia = "All";
        }

        #region Properties

        [Browsable(true)]
        [Category("Style sheet")]
        [DefaultValue("")]
        [Description("The url to the style sheet.")]
        [UrlProperty("*.css")]
        public string CssUrl
        {
            get; set;
        }

        [Browsable(true)]
        [Category("Style sheet")]
        [DefaultValue("All")]
        [Description("The target media(s) of the style sheet. See http://www.w3.org/TR/REC-CSS2/media.html for more information.")]
        public string TargetMedia
        {
            get; set;
        }

        [Browsable(true)]
        [Category("Style sheet")]
        [DefaultValue(EmbedType.Link)]
        [Description("Specify how to embed the style sheet on the page.")]
        public EmbedType Type
        {
            get; set;
        }

        [Browsable(false)]
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public string InlineStyle
        {
            get; set;
        }

        [Browsable(true)]
        [Category("Conditional comment")]
        [DefaultValue("")]
        [Description("Specifies a conditional comment expression to wrap the style sheet in. See http://msdn.microsoft.com/en-us/library/ms537512.aspx")]
        public string ConditionalCommentExpression
        {
            get; set;
        }

        [Browsable(true)]
        [Category("Conditional comment")]
        [DefaultValue(CommentType.DownlevelHidden)]
        [Description("Whether to reveal the conditional comment expression to downlevel browsers. Default is to hide. See http://msdn.microsoft.com/en-us/library/ms537512.aspx")]
        public CommentType ConditionalCommentType
        {
            get; set;
        }

        [Browsable(true)]
        [Category("Behavior")]
        public override string SkinID { get; set; }

        #endregion

        protected override void Render(HtmlTextWriter writer)
        {            
            // add empty line to make output pretty
            writer.WriteLine();

            // prints out begin condition comment tag
            if (!string.IsNullOrEmpty(ConditionalCommentExpression))
                writer.WriteLine(ConditionalCommentType == CommentType.DownlevelRevealed ? "<!{0}>" : "<!--{0}>",
                                 ConditionalCommentExpression);

            if (!string.IsNullOrEmpty(CssUrl))
            {               
                // add shared attribute
                writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");

                // render either import or link tag
                if (Type == EmbedType.Link)
                {
                    // <link href=\"{0}\" type=\"text/css\" rel=\"stylesheet\" media=\"{1}\" />
                    writer.AddAttribute(HtmlTextWriterAttribute.Href, ResolveUrl(CssUrl));
                    writer.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
                    writer.AddAttribute("media", TargetMedia);
                    writer.RenderBeginTag(HtmlTextWriterTag.Link);
                    writer.RenderEndTag();
                }
                else
                {
                    // <style type="text/css">@import "modern.css" screen;</style>
                    writer.RenderBeginTag(HtmlTextWriterTag.Style);
                    writer.Write("@import \"{0}\" {1};", ResolveUrl(CssUrl), TargetMedia);
                    writer.RenderEndTag();
                }
            }

            if(!string.IsNullOrEmpty(InlineStyle))
            {
                // <style type="text/css">... inline style ... </style>
                writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
                writer.RenderBeginTag(HtmlTextWriterTag.Style);
                writer.Write(InlineStyle);
                writer.RenderEndTag();
            }

            // prints out end condition comment tag
            if (!string.IsNullOrEmpty(ConditionalCommentExpression))
            {
                // add empty line to make output pretty
                writer.WriteLine();
                writer.WriteLine(ConditionalCommentType == CommentType.DownlevelRevealed ? "<![endif]>" : "<![endif]-->");
            }
        }
    }

    public enum EmbedType
    {        
        Link = 0,
        Import = 1,
    }

    public enum CommentType
    {
        DownlevelHidden = 0,
        DownlevelRevealed = 1
    }
}

所以,你们觉得呢?这是一个很好的解决了asp.net主题的问题?约在code是什么?我真的想一些关于它的投入,特别是关于设计时体验。

So what do you guys think? Is this a good solution to the asp.net theme problem? And what about the code? I would really like some input on it, especially in regards to the design time experience.

我上传了的Visual Studio解决方案的压缩版本包含该项目,如果有人有兴趣。

I uploaded a zipped version of the Visual Studio solution that contains the project, in case anyone is interested.

最好的问候,埃伊尔。

推荐答案

找到了答案,以我自己的问题。

Found the answer to my own question.

原因我在设计模式得到渲染错误,是一个明显的错误在Visual Studio SP1,的微软还没有修复

The reason for the rendering errors I am getting in design mode, is an apparent bug in Visual Studio SP1, which Microsoft has yet to fix.

所以不如预期,也是在设计模式,只要你只是包含在pre编译的程序集的自定义控件,而不是通过在同一个解决方案的另一个项目上code ++工程。

So the above code works as expected, also in design mode, as long as you just include the custom controls in a pre compiled assembly, and not through another project in the same solution.

请参阅上面的链接了解如何以及为什么更详细的解释。

See the link above for a more detailed explanation of how and why.

这篇关于如何把样式表控制在ASP.NET主题与StylePlaceHolder和样式的控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆