WebControl with embedded stylesheet rendering at design time
Posted by Justin on Feb 20, 2009 in Programming |
I have a working solution to the embedded image in an embedded stylesheet problem, but I would appreciate any suggestions for improvement. This does its own substitution of the CSS file in the Designer class for the IDE. Transparency in PNGs don’t work so far, however. I’ll post some of the code here, but a full example solution is available for download. I’d love to hear comments on this. Thank you!
AssemblyInfo.cs (partial)
// Styles [assembly: WebResource("GizmonicInstitute.WebControls.SampleControl.css", "text/css", PerformSubstitution = true)] // Images [assembly: WebResource("GizmonicInstitute.WebControls.cog.png", "image/png")] [assembly: WebResource("GizmonicInstitute.WebControls.inner_shadow.png", "image/png")]
SampleControl.css
.SampleControl_TextBox { padding: 4px 0 0 4px; height: 1.5em; border: solid 1px Black; background-color: Yellow; background-image: url('<%=WebResource("GizmonicInstitute.WebControls.inner_shadow.png")%>'); background-repeat: no-repeat; background-position: left top; } .SampleControl_Button { width: 2em; height: 2em; border-width: 2px; background-color: #EAEAEA; background-image: url('<%=WebResource("GizmonicInstitute.WebControls.cog.png")%>'); background-repeat: no-repeat; background-position: center center; }
SampleControl.cs
1 #region Using directives 2 using System; 3 using System.Collections.Generic; 4 using System.ComponentModel; 5 using System.Text; 6 using System.Web; 7 using System.Web.UI; 8 using System.Web.UI.HtmlControls; 9 using System.Web.UI.WebControls; 10 #endregion 11 12 namespace GizmonicInstitute.WebControls { 13 14 [Designer(typeof(SampleControlDesigner))] 15 [DefaultProperty("TextBoxText")] 16 [ToolboxData("<{0}:SampleControl runat=server>")] 17 public class SampleControl : CompositeControl { 18 19 protected Label lblSample; 20 protected TextBox txtSample; 21 protected Button btnSample; 22 23 [Bindable(true)] 24 [Category("Appearance")] 25 [DefaultValue("")] 26 [Description("Gets or sets the text caption displayed in the Button control.")] 27 public string LabelText { 28 get { 29 object o = ViewState["LabelText"]; 30 return (o == null) ? String.Empty : (string)o; 31 } 32 set { 33 ViewState["LabelText"] = value; 34 RecreateChildControls(); 35 } 36 } 37 38 [Bindable(true)] 39 [Category("Appearance")] 40 [DefaultValue("")] 41 [Description("Gets or sets the text caption displayed in the Button control.")] 42 public string TextBoxText { 43 get { 44 object o = ViewState["TextBoxText"]; 45 return (o == null) ? String.Empty : (string)o; 46 } 47 set { 48 ViewState["TextBoxText"] = value; 49 RecreateChildControls(); 50 } 51 } 52 53 [Bindable(true)] 54 [Category("Appearance")] 55 [DefaultValue("")] 56 [Description("Gets or sets the text caption displayed in the Button control.")] 57 public string ButtonText { 58 get { 59 object o = ViewState["ButtonText"]; 60 return (o == null) ? String.Empty : (string)o; 61 } 62 set { 63 ViewState["ButtonText"] = value; 64 RecreateChildControls(); 65 } 66 } 67 68 protected void btnSample_Click(Object sender, EventArgs e) { 69 txtSample.Text = String.Format("Clicked at {0:h:mm:ss tt}", DateTime.Now ); 70 } 71 72 protected override void CreateChildControls() { 73 lblSample = new Label(); 74 txtSample = new TextBox(); 75 btnSample = new Button(); 76 77 lblSample.Text = this.LabelText; 78 txtSample.Text = this.TextBoxText; 79 btnSample.Text = this.ButtonText; 80 81 txtSample.CssClass = "SampleControl_TextBox"; 82 btnSample.CssClass = "SampleControl_Button"; 83 btnSample.Click += new EventHandler(btnSample_Click); 84 85 Controls.Add(lblSample); 86 Controls.Add(txtSample); 87 Controls.Add(btnSample); 88 } 89 90 protected override void OnPreRender(EventArgs e) { 91 // Add embedded style sheet to parent page 92 HtmlLink cssLink = new HtmlLink(); 93 cssLink.ID = "SampleControlCss"; 94 cssLink.Href = Page.ClientScript.GetWebResourceUrl(this.GetType(), "GizmonicInstitute.WebControls.SampleControl.css"); 95 cssLink.Attributes.Add("rel", "stylesheet"); 96 cssLink.Attributes.Add("type", "text/css"); 97 bool CssLinkAlreadyExists = false; 98 foreach (Control headctrl in Page.Header.Controls) { 99 if (headctrl.ID == cssLink.ID) { 100 CssLinkAlreadyExists = true; 101 break; 102 } 103 } 104 if (!CssLinkAlreadyExists) { 105 Page.Header.Controls.AddAt(0, cssLink); 106 } 107 } 108 109 } 110 }
SampleControlDesigner.cs
1 #region Using directives 2 using System; 3 using System.Web.UI; 4 using System.Text.RegularExpressions; 5 #endregion 6 7 namespace GizmonicInstitute.WebControls { 8 9 public class SampleControlDesigner : System.Web.UI.Design.ControlDesigner { 10 public override string GetDesignTimeHtml() { 11 System.Reflection.Assembly l_asm = System.Reflection.Assembly.GetExecutingAssembly(); 12 System.IO.Stream l_css_res = l_asm.GetManifestResourceStream("GizmonicInstitute.WebControls.SampleControl.css"); 13 System.IO.StreamReader l_stream = new System.IO.StreamReader(l_css_res); 14 string ls_css = l_stream.ReadToEnd(); 15 16 const string SUBSTITUTION_PATTERN = @"(<%=)\s*(WebResource\("")(?.+)\s*(""\)%>)"; 17 Regex theRegex = new Regex(SUBSTITUTION_PATTERN); 18 ls_css = theRegex.Replace(ls_css, new MatchEvaluator(PerformSubstitution)); 19 20 return "" + base.GetDesignTimeHtml(); 21 } 22 23 private string PerformSubstitution(Match m) { 24 SampleControl thisWeightControl = (SampleControl)Component; 25 string replacedString = m.ToString(); 26 replacedString = replacedString.Replace(m.Value, thisWeightControl.Page.ClientScript.GetWebResourceUrl(this.GetType(), m.Groups["resourceName"].Value)); 27 return replacedString; 28 } 29 } 30 31 }