代码之家  ›  专栏  ›  技术社区  ›  NightOwl888 Jabrwoky

ASP.NET自定义控件-只有一次包含嵌入式CSS引用的最佳方法是什么?

  •  9
  • NightOwl888 Jabrwoky  · 技术社区  · 15 年前

    问题是:我正在将一个CSS文件嵌入到一个包含多个控件的自定义控件库中。我想为所有控件共享相同的CSS文件,而不管它们在给定表单上有多少实例。当表单上有多个控件时,我希望在ASP.NET第页。

    Public Sub IncludeStyles(ByVal Page As System.Web.UI.Page)
        'Don't include the reference if it already exists...
        If Page.Header.FindControl("MyID") Is Nothing Then
            Dim cssUrl As String = Page.ClientScript.GetWebResourceUrl(GetType(Common), StylePath)
    
            Dim css As New System.Web.UI.HtmlControls.HtmlGenericControl("link")
            With css
                .Attributes.Add("rel", "stylesheet")
                .Attributes.Add("type", "text/css")
                .Attributes.Add("href", cssUrl)
                .ID = "MyID"
            End With
    
            Page.Header.Controls.Add(css)
        End If
    End Sub
    

    FindControl() 查看窗体上是否存在控件。尽管我正在使用命名容器,但它似乎仍在工作,我确信有某种方法可以打破这一点。在表单上添加另一个具有相同ID的控件肯定是。。。

    注:在 ClientScript.RegisterClientScriptResource() 方法有一个接受.NET类型的参数,此类型可用于确保每页仅输出一次代码。不幸的是,这个方法只适用于JavaScript文件引用。如果有一个内置的等效CSS引用,那将是我的首选。

    我发现了一种更优雅的方法 here 通过使用Page.ClientScript.RegisterClientScriptBlock页告诉它您包含了自己的脚本标记,但是正如Rick指出的,这并没有将脚本添加到html头标记中,也不符合xhtml。

    我看到另一个有趣的想法 this thread

    Chris Lively提出了一个更好的解决方案,它需要更少的代码。这是我用新解决方案修改的功能:

    Public Sub IncludeStyles(ByVal Page As System.Web.UI.Page)
        If Not Page.ClientScript.IsClientScriptBlockRegistered(StyleName) Then
            Dim cssUrl As String = Page.ClientScript.GetWebResourceUrl(GetType(Common), StylePath)
    
            Dim css As New System.Web.UI.HtmlControls.HtmlGenericControl("link")
            With css
                .Attributes.Add("href", cssUrl)
                .Attributes.Add("rel", "stylesheet")
                .Attributes.Add("type", "text/css")
            End With
    
            Page.Header.Controls.Add(css)
            Page.ClientScript.RegisterClientScriptBlock(GetType(Page), StyleName, "")
        End If
    End Sub
    

    关于这个解决方案有几点需要注意。在他最初的帖子中,Chris使用了 IsClientScriptIncludeRegistered() 方法,它不是 RegisterClientScriptBlock() 方法。要正确执行此功能,必须使用 IsClientScriptBlockRegistered() .

    RegisterClientStriptBlock() IsClientScriptBlockRegistered()

    尽管无可否认,这个解决方案有点像黑客,但它a)不需要太多代码或开销,b)在页面上生成所需的输出,c)是符合xhtml的代码。

    3 回复  |  直到 9 年前
        1
  •  9
  •   ChrisLively    15 年前

    为了防止从服务器控件发送css文件时出现重复,我们执行以下操作:

    if (!Page.ClientScript.IsClientScriptBlockRegistered("SoPro." + id)) {
        HtmlLink cssLink = new HtmlLink();
        cssLink.Href = cssLink.Href = Page.ClientScript.GetWebResourceUrl(this.GetType(), styleSheet);
        cssLink.Attributes.Add("rel", "stylesheet");
        cssLink.Attributes.Add("type", "text/css");
        this.Page.Header.Controls.Add(cssLink);
        this.Page.ClientScript.RegisterClientScriptBlock(typeof(System.Web.UI.Page), "SoPro." + id, String.Empty);
    }
    

    首先,我们测试命名脚本是否以前注册过。如果没有,我们就加进去。

        2
  •  3
  •   Community Mohan Dere    9 年前

    我不知道为什么,但你的解决方案对我不起作用ClientScript.IsClientScriptBlockRegistered呼叫总是返回false。但是约翰·布莱索对你已经提供的链接的建议( here

    public static void IncludeStylesheet(Page page, string href, string styleID)
    {
        //Prevent the stylesheet being included more than once
         styleID = "_" + styleID;
        if (HttpContext.Current.Items[styleID] == null)
        {
            HtmlLink htmlLink = new HtmlLink();
            htmlLink.Href = href;
            htmlLink.Attributes.Add("rel", "stylesheet");
            htmlLink.Attributes.Add("type", "text/css");
            page.Header.Controls.Add(htmlLink);
            HttpContext.Current.Items[styleID] = true;
        }
    }
    
        3
  •  0
  •   William    15 年前

    为什么不在最初创建CSS时设置为true的控件中创建一个私有布尔变量呢。然后可以在调用方法时检查此项,以查看是否已设置css。下面的例子(我的VB生锈了,所以可能有点错)

    Private _hasCss As Boolean = False
    
    Public Sub IncludeStyles(ByVal Page As System.Web.UI.Page)
        'Don't include the reference if it already exists...
        If Not _hasCss Then
            Dim cssUrl As String = Page.ClientScript.GetWebResourceUrl(GetType(Common), StylePath)
    
            Dim css As New System.Web.UI.HtmlControls.HtmlGenericControl("link")
            With css
                .Attributes.Add("rel", "stylesheet")
                .Attributes.Add("type", "text/css")
                .Attributes.Add("href", cssUrl)
                .ID = "MyID"
            End With
    
            Page.Header.Controls.Add(css)
            _hasCss = True
    
        End If
    End Sub
    
    推荐文章