Пользовательский элемент управления ASP.NET. Какой лучший способ включить встроенную ссылку CSS только один раз?

Проблема: я встраиваю файл CSS в библиотеку пользовательских элементов управления с несколькими элементами управления. Я хочу использовать один и тот же файл CSS для всех элементов управления, независимо от того, сколько их экземпляров находится в заданной форме. Когда в форме находится более одного элемента управления, я бы хотел, чтобы в заголовке HTML страницы ASP.NET была ровно 1 ссылка на файл CSS.

Вот что я придумала (пока):

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() чтобы увидеть, существует ли элемент управления в форме. Несмотря на то, что я использую именование контейнеров, и оно все еще работает, я уверен, что есть какой-то способ это сломать. Добавление другого элемента управления в форму с тем же идентификатором, безусловно, один ...

Вопрос: что может быть лучше, если элемент управления заголовка добавляется в заголовок HTML только один раз?

Обратите вниманиеClientScript.RegisterClientScriptResource() Метод имеет параметр, который принимает тип .NET, и этот тип можно использовать для обеспечения вывода кода только один раз на страницу. К сожалению, этот метод работает только со ссылками на файлы JavaScript. Если есть встроенный эквивалент для ссылок CSS, это было бы моим предпочтением.

Обновить:

Я обнаружил немного более элегантный способ сделать этоВот используя Page.ClientScript.RegisterClientScriptBlock и сообщая, что вы включаете собственные теги сценария, однако, как указывает Рик, это не добавляет сценарий к тегу заголовка html и также не совместимо с xhtml.

Обновление 2:

Я увидел еще одну интересную идею оэта тема, но циклический просмотр коллекции элементов управления не очень хорошее решение и добавляет много накладных расходов, если у вас есть несколько ссылок и несколько элементов управления на странице.

Крис Лайвли придумал лучшее решение, которое требует меньше кода. Вот моя функция, измененная новым решением:

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

Несколько вещей, чтобы отметить об этом решении. В своем первоначальном посте Крис использовалIsClientScriptIncludeRegistered() метод, который не был соответствующим методомRegisterClientScriptBlock() метод. Чтобы сделать эту функцию правильно, тест должен быть сделан сIsClientScriptBlockRegistered().

Кроме того, обратите особое внимание на тип, который передаетсяRegisterClientScriptBlock(), Я передал пользовательский тип данных этому методу (одинаковый для всех моих элементов управления), но он не был зарегистрирован таким образом, чтоIsClientScriptBlockRegistered() тест будет работать. Для того, чтобы он функционировал, текущий объект Page должен быть передан как аргумент Type.

Хотя, по общему признанию, это решение выглядит как хак, оно а) не требует большого количества кода или служебных данных, б) создает точно желаемый результат на странице и в) является кодом, совместимым с xhtml.

Ответы на вопрос(3)

Ваш ответ на вопрос