Sự cố: Tôi đang nhúng tệp CSS vào thư viện điều khiển tùy chỉnh với một số điều khiển. Tôi muốn chia sẻ cùng một tệp CSS cho tất cả các điều khiển bất kể có bao nhiêu phiên bản của chúng trên một biểu mẫu nhất định. Khi có nhiều hơn một điều khiển trên biểu mẫu, tôi muốn chính xác 1 tham chiếu đến tệp CSS trong tiêu đề HTML của trang ASP.NET.Kiểm soát tùy chỉnh ASP.NET - Cách tốt nhất để bao gồm tham chiếu CSS nhúng chỉ một lần là gì?
Dưới đây là những gì tôi đã đưa ra (cho đến nay):
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, nó hoạt động ... nhưng lỗ hổng rõ ràng ở đây là việc sử dụng FindControl()
để xem nếu việc kiểm soát tồn tại trên hình thức . Mặc dù tôi đang sử dụng các thùng chứa đặt tên và nó vẫn có vẻ hoạt động, tôi chắc chắn có một số cách để phá vỡ điều này. Việc thêm một điều khiển khác vào biểu mẫu có cùng ID chắc chắn là một ...
Câu hỏi: Cách tốt hơn để đảm bảo kiểm soát tiêu đề chỉ được thêm vào tiêu đề HTML chính xác một lần là gì?
Lưu ý: Phương thức ClientScript.RegisterClientScriptResource()
có tham số chấp nhận loại .NET và loại này có thể được sử dụng để đảm bảo mã chỉ xuất mỗi lần trên một trang. Rất tiếc, phương thức này chỉ hoạt động với các tham chiếu tệp JavaScript. Nếu có một tương đương được xây dựng trong cho tài liệu tham khảo CSS, đó sẽ là sở thích của tôi.
Cập nhật:
tôi phát hiện ra một cách nhẹ thanh lịch hơn để làm điều này bằng cách sử dụng here Page.ClientScript.RegisterClientScriptBlock và nói với nó, bạn được bao gồm các thẻ script riêng của bạn, tuy nhiên như Rick chỉ ra, điều này doesn' t thêm tập lệnh vào thẻ đầu html và cũng không tương thích với xhtml.
Cập nhật 2:
tôi thấy một ý tưởng thú vị về this thread, nhưng vòng lặp thông qua bộ sưu tập các điều khiển không phải là một giải pháp rất tốt và cho biết thêm rất nhiều chi phí nếu bạn có nhiều tài liệu tham khảo và một số điều khiển trên trang .
Chris Sống động với giải pháp tốt hơn yêu cầu ít mã hơn. Đây là chức năng của tôi được thay đổi bằng giải pháp mới:
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
Một vài điều cần lưu ý về giải pháp này. Trong bài đăng gốc của mình, Chris đã sử dụng phương thức IsClientScriptIncludeRegistered()
không phải là phương pháp tương ứng với phương thức RegisterClientScriptBlock()
. Để thực hiện chức năng này một cách chính xác, thử nghiệm phải được thực hiện với IsClientScriptBlockRegistered()
.
Ngoài ra, hãy chú ý cẩn thận đến loại được chuyển đến RegisterClientScriptBlock()
. Tôi đã thông qua một kiểu dữ liệu tùy chỉnh cho phương thức này (giống nhau trên tất cả các điều khiển của tôi), nhưng nó không đăng ký theo cách mà thử nghiệm IsClientScriptBlockRegistered()
sẽ hoạt động. Để cho nó hoạt động, đối tượng Trang hiện tại phải được chuyển thành đối số Type.
Mặc dù phải thừa nhận rằng giải pháp này hơi giống như hack, a) không yêu cầu nhiều mã hoặc phí, b) tạo ra chính xác kết quả mong muốn trên trang và c) là mã tuân thủ xhtml.
Về mặt lý thuyết, tại sao là css không nằm trong tập tin css chính của trang web đó được nạp và lưu trữ của khách hàng? – jball
Đây là thư viện điều khiển có thể được sử dụng trong bất kỳ trang web nào và tôi thích sử dụng một CSS riêng biệt (có thể dễ dàng bị ghi đè) thay vì mã hóa cứng tất cả nội tuyến CSS (như Microsoft đã làm trong nhiều trường hợp). Nói cách khác, các điều khiển của tôi hoàn toàn không biết về trang web mà chúng được lưu trữ trong. – NightOwl888
Trình dịch vụ w3validator không thích ampersand chưa mã hóa mà GetWebResourceUrl trả về. Để khắc phục mã hóa url bằng Page.Server.HtmlEncode (url) – daniatic