I am in the process of learning Server Controls Development and looking for proper instructions to enable setting the data declaratively through source. For example the dropdownlist control provides declarative data like below
<asp:DropDownList id="dropdown" runat="server">
<asp:ListItem text="Project Initiation" value="1"></asp:ListItem>
<asp:ListItem text="Documentation" value="2"></asp:ListItem>
</asp:DropDownList>
similarly i am looking for declaratively providing data to my simple menu control that displays image surrounded by image like below (the output markup) from a datasource
<a>
<img src="" />
</a>
Please do not point me to a link, the least anyone can do is that. I would like a clear explanation of what needs to be done for providing such functionality. I would like my final source to look like below
<asp:sidebar runat="server" id="sb">
<asp:sidebaritem navigateurl="" imageurl="" label=""></asp:sidebaritem>
</asp:sidebar>
sidebar item class is defined below and i have a property too
public class SidebarItem
{
private string _navigateUrl;
public string NavigateUrl
{
get { return _navigateUrl; }
set { _navigateUrl = value; }
}
. . .
}
[PersistenceMode(PersistenceMode.InnerProperty)]
[NotifyParentProperty(true)]
public ICollection<SidebarItem> Items
{
get { return _sidebarItems; }
set { _sidebarItems = value; }
}
The answer you are looking for is here: http://msdn.microsoft.com/en-us/library/9txe1d4x.aspx
As you've asked for more than just a link, here's an example solution specific to your scenario:
[
AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal),
DefaultProperty("Items"),
ParseChildren(true, "Items"),
ToolboxData("<{0}:SideBar runat=\"server\"> </{0}:SideBar>")
]
public class SideBar : WebControl
{
private ArrayList itemsList;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
//[Editor(typeof(ContactCollectionEditor), typeof(UITypeEditor))]
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public ArrayList Items
{
get
{
if (itemsList == null)
{
itemsList = new ArrayList();
}
return itemsList;
}
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
foreach (object o in itemsList)
{
SideBarItem item = (SideBarItem)o;
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.AddAttribute(HtmlTextWriterAttribute.Href, item.NavigateUrl);
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.AddAttribute(HtmlTextWriterAttribute.Src, item.ImageUrl);
writer.RenderBeginTag(HtmlTextWriterTag.Img);
writer.RenderEndTag(); // Img
writer.RenderEndTag(); // A
writer.RenderEndTag(); // Li
}
writer.RenderEndTag(); // Ul
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public class SideBarItem
{
public SideBarItem()
: this(String.Empty, String.Empty, String.Empty)
{
}
public SideBarItem(string imgUrl, string navUrl, string label)
{
ImageUrl = imgUrl;
NavigateUrl = navUrl;
Label = label;
}
[DefaultValue("")]
[NotifyParentProperty(true)]
public String ImageUrl { get; set; }
[DefaultValue("")]
[NotifyParentProperty(true)]
public String NavigateUrl { get; set; }
[DefaultValue("")]
[NotifyParentProperty(true)]
public String Label { get; set; }
}
Then in the ASPX file would be as such:
Referenced
<%@ Register Assembly="MyProject" Namespace="MyProject" TagPrefix="cc1" %>
Implemented
<cc1:SideBar ID="SideBar1" runat="server">
<cc1:SideBarItem ImageUrl="#" NavigateUrl="#" />
<cc1:SideBarItem ImageUrl="#" NavigateUrl="#" />
</cc1:SideBar>