Alright, this one really bugged me forever! Took me 3 days to figure it out, which is extremely long in most of my situations!
Granted this was also my first server control… so I had a lot to learn. lol
Anyway let’s get down to business. First off if you know anything about custom server controls you know you can’t easily set the values inside the control. It’s a pain! The controls I want to create are more of a code base, such as with the master and child pages. I want to simply format a panel object and input my own code and have it come out beautified.
So how do we do this?
Well with custom controls I like to start with the HTML result:
<customcontrol:boxy id=”ccboxy” runat=”server”>
<asp:label id=”lblHelloWorld” runat=”server” />
</customcontrol:body>
Alright looks simple right? Well what we are going to do is first create our control to duplicate this:
<asp:panel id=”pnlBoxy” runat=”server”>
<asp:label id=”lblHelloWorld” runat==”server” />
</asp:panel>
Well panels are very different from normal controls since they actually are designed to be containers, meaning you put code inside them. Normal controls will simply only work for that control and reject any other code as garbage. Itemplates don’t fix this either and are a lot more work.
To being let’s just throw out all the code at once! Makes it easier to explain!
Imports System
Imports System.Web
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Imports System.Security.Permissions
Namespace custom.ServerControls
< _
AspNetHostingPermission(SecurityAction.Demand, _
Level:=AspNetHostingPermissionLevel.Minimal), _
AspNetHostingPermission(SecurityAction.InheritanceDemand, _
Level:=AspNetHostingPermissionLevel.Minimal), _
DefaultProperty("Text"), _
ParseChildren(False), _
ToolboxData( _
"<{0}:Boxy runat=""server""></{0}:Boxy>") _
> _
Public Class Boxy
Inherits Panel
< _
Bindable(True), _
Category("Boolean"), _
DefaultValue(True), _
Description("Set visibilty of icon object."), _
Localizable(True) _
> _
Public Overridable Property Icon() As Boolean
Get
If ViewState("Icon") IsNot Nothing Then
Return CType(ViewState("Icon"), Boolean)
Else
Return True
End If
End Get
Set(ByVal value As Boolean)
ViewState("Icon") = value
End Set
End Property
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
writer.WriteLine("<div style=""border:5px solid black;"">")
If Icon Then
writer.WriteLine("<img src=""your icon image source"" />")
End If
MyBase.RenderContents(writer)
writer.WriteLine("</div>")
End Sub
End Class
End Namespace
So now with that complex code out, let me begin to explain what is going on.
Imports System
Imports System.Web
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Imports System.Security.Permissions
In the above imports section we just need to go ahead and import the basics. I didn’t import any designer namespaces since I don’t typically use designer mode, and it makes the code more complex if I add it. If you wish to learn more, you can learn it on msdn’s site, but for now just get the basics down.
With the above namespaces collected you can go ahead and start your meta tags. Yes meta tags, they are also in asp.net!
to make it really simple to understand meta tags in VB.Net are setup like…
<metatag>sub x()
It has to be directly on the same line! which is why you see a lot of _s to allow line breaks without breaking up the code.
For now don’t worry about the meta properities too much. Just know you have to set permissions etc. Most of it is for visual study, but some you do need for the actual control.
Next you name the class. We have it as boxy, since that is the name of the control. So when you go and type <{0}:boxy> you access the boxy class.
Typically you see custom controls use WebControl or CompositeControl. In this case we are going to cheat and go right for the panel class! This is the KEY to getting this to work!
After that comes two things. First is the optional icon property. You don’t need this, but I wanted to show that you can make your own custom properties.
To access the proprety just type <{0}:boxy icon=”true/false”>
This will allow the image to show up or not. Again optional but it helps to know you can do it! To override the property just use overrides and use the code as shown above. You can learn more about it, but this post is more just to show you how to use a panel as a custom control.
Ok now skipping ahead to the using that panel class to our advantage and overriding its code!
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
writer.WriteLine(“<div style=”"border:5px solid black;”">”)
If Icon Then
writer.WriteLine(“<img src=”"your icon image source”" />”)
End If
MyBase.RenderContents(writer)
writer.WriteLine(“</div>”)
End Sub
That there is the main part of the code! We simply override the rendercontents method! What this does instead of jumping ahead and just inputing the panel controls into the panel control, we instead snatch it before it finishes and add some of our own custom code!
It’s a simple htmltextwriter object so it’s really easy to use, just look it up on msdn if you’re not sure.
You take writer and use the writeline method to add the begining code. Don’t worry this won’t edit the contents of writer. I know it seems odd a little but writeline doesn’t effect the htmltextwriter at all, it just injects code into the page where the panel control is at.
After you finish all that you can use an If statement to check if Icon is set true or false. If it is true, go ahead and write the line for the image tag text.
After that we override the render method with mybase, the contorl, .rendercontents(writer) writer is whatever is inside the custom control!
After that we just add another line of code with the writeline to close the tags! And there you have it! The code is now working, now to register the tags into the aspx page.
<% @ Register TagPrefix=”customcontrol” Namespace=”custom.servercontrols” %>
Then we go ahead and use the code as shown before and it works!
<customcontrol:boxy runat=”server”>
<label text=”It’s boxy!” runat=”server” />
</customcontrol:boxy>
output: