Problem: Osadzam plik CSS w niestandardowej bibliotece kontrolnej z kilkoma kontrolkami. Chcę udostępnić ten sam plik CSS dla wszystkich formantów, niezależnie od tego, ile wystąpiło ich w danym formularzu. Jeśli w formularzu znajduje się więcej niż jeden formant, chciałbym dokładnie 1 referencję do pliku CSS w nagłówku HTML strony ASP.NET.Niestandardowa kontrola programu ASP.NET - Jaki jest najlepszy sposób dołączenia odniesienia do osadzonego CSS tylko raz?
Oto co mam wymyślić (jak dotąd):
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
Ok, to działa ... ale oczywistą wadą jest tu wykorzystanie FindControl()
aby sprawdzić, czy kontrola istnieje w formie . Chociaż używam nazw kontenerów i nadal wydaje się działać, jestem pewien, że jest jakiś sposób, aby to przełamać. Dodanie kolejnej kontroli w formularzu o tym samym identyfikatorze to z pewnością jeden ...
Pytanie: Jaki jest lepszy sposób na zapewnienie, że kontrola nagłówka jest dodawana do nagłówka HTML tylko raz?
Uwaga: Metoda ClientScript.RegisterClientScriptResource()
ma parametr, który akceptuje typ .NET i ten typ może być używany w celu zapewnienia, że kod jest wyprowadzany tylko raz na stronę. Niestety ta metoda działa tylko z odwołaniami do plików JavaScript. Jeśli istnieje wbudowany odpowiednik dla referencji CSS, byłby to mój wybór.
Aktualizacja:
odkryłem nieco bardziej elegancki sposób to zrobić za pomocą Page.ClientScript.RegisterClientScriptBlock here i mówiąc to jesteś w tym własne znaczniki skryptów, jednak jak Rick wskazuje to robi” t dodaj skrypt do znacznika html head, a także nie jest zgodny z xhtml.
Aktualizacja 2:
Widziałem inny ciekawy pomysł na this thread, ale zapętlenie poprzez zbieranie kontrole nie jest to bardzo dobre rozwiązanie i dodaje dużo napowietrznych, jeśli masz kilka odniesień i kilka formantów na stronie .
Chris Lively wymyślił lepsze rozwiązanie, które wymaga mniej kodu. Oto moja funkcja zmieniona w nowym rozwiązaniu:
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
Kilka rzeczy na uwagę na temat tego rozwiązania. W swoim oryginalnym poście Chris użył metody IsClientScriptIncludeRegistered()
, która nie była odpowiednią metodą dla metody RegisterClientScriptBlock()
. Aby funkcja działała poprawnie, test należy wykonać przy pomocy IsClientScriptBlockRegistered()
.
Należy również zwrócić szczególną uwagę na typ przekazywany do RegisterClientScriptBlock()
. Do tej metody przekazałem niestandardowy typ danych (taki sam we wszystkich kontrolach), ale nie zarejestrował się w taki sposób, aby test IsClientScriptBlockRegistered()
zadziałał. Aby to działało, bieżący obiekt strony musi zostać przekazany jako argument Type.
Wprawdzie to rozwiązanie wydaje się nieco podobne do hackowania, to a) nie wymaga dużej ilości kodu ani kosztów ogólnych, b) daje dokładnie pożądane wyniki na stronie, a c) jest zgodny z XHTML.
koncepcyjnej, dlaczego jest css nie jest częścią głównego pliku css witryny, które jest pobierany i buforowane przez klienta? – jball
To jest biblioteka kontrolna, która teoretycznie może być używana na dowolnej stronie internetowej i wolę używać oddzielnego CSS (który może być łatwo zastąpiony) zamiast twardego kodowania wszystkich CSS inline (jak Microsoft zrobił w wielu przypadkach). Innymi słowy, moje kontrole powinny być całkowicie nieświadome witryny, w której są hostowane. – NightOwl888
W3validator nie lubi niekodowanych ampersand, które zwraca GetWebResourceUrl. Aby naprawić, który zakoduje adres URL z Page.Server.HtmlEncode (url) – daniatic