在项目开发中经常会用到选项卡控件,网上也有很多,其实只是简单的功能,很多却实现的很复杂,功能很强大,并不是我需要的。
下面来实现一个简单的TabControl 。
先看演示:
>
运行出来的效果:
下面开始贴代码:
[ControlBuilder(typeof(TabItemBuilder))]
[DefaultProperty("TabSelectedIndex")] [ToolboxData("<{0}:TabControl runat=server></{0}:TabControl>")] [ParseChildren(typeof(TabItem))] [Description("选项卡Web控件")] [Designer(typeof(Hxj.Web.UI.Design.HxjControlDesigner))] public class TabControl : WebControl
其中[ParseChildren(typeof(TabItem))] 表示控件嵌套的子节点必须是TabItem控件,就是上面的示例代码。
控件比较简单值定义了两个自定义属性:
[Description("默认显示的选项卡项")] public int TabSelectedIndex
[Description("自定义选项卡CSS样式")] public string HeaderCssClass
下面是控件输出HTML:
int totalTab = TabItems.Count; if (!string.IsNullOrEmpty(HeaderCssClass)) { writer.AddAttribute(HtmlTextWriterAttribute.Class, HeaderCssClass); } else { writer.AddAttribute(HtmlTextWriterAttribute.Class, "tabheader"); } writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "header"); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.RenderBeginTag(HtmlTextWriterTag.Ul); for (int i = 0; i < totalTab; i++) { if (i == TabSelectedIndex) { writer.AddAttribute(HtmlTextWriterAttribute.Class, "current"); } if (!TabItems[i].Visible) { writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none"); } writer.RenderBeginTag(HtmlTextWriterTag.Li); writer.AddAttribute(HtmlTextWriterAttribute.Href, "javascript:void(0)"); writer.AddAttribute(HtmlTextWriterAttribute.Onclick, string.Concat("htabs('", this.ClientID, "',", i.ToString(), ")")); writer.AddAttribute(HtmlTextWriterAttribute.Title, TabItems[i].ToolTip); writer.RenderBeginTag(HtmlTextWriterTag.A); writer.Write(TabItems[i].Text); writer.RenderEndTag(); writer.RenderEndTag(); } writer.RenderEndTag(); writer.RenderEndTag(); for (int i = 0; i < totalTab; i++) { if (i != TabSelectedIndex) { writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none"); } writer.AddAttribute(HtmlTextWriterAttribute.Id, string.Concat(this.ClientID, "Content", i.ToString())); writer.RenderBeginTag(HtmlTextWriterTag.Div); TabItems[i].RenderControl(writer); writer.RenderEndTag(); }
输出的代码也是很简单。
其实也可以这么写:
<hxj:TabControl ID="TabControl1" runat="server" TabSelectedIndex="0"> <tab Text="123"> tab123 </tab> </hxj:TabControl>
主要是由于TabControl的特性
[ControlBuilder(typeof(TabItemBuilder))]
其中TabItemBuilder是自定义的ControlBuilder。
代码如下:
public class TabItemBuilder : ControlBuilder { public override Type GetChildControlType(string tagName, IDictionary attribs) { if (String.Compare(tagName, "tab", true) == 0) return typeof(TabItem); else return null; } }
即通过ControlBuilder 来实现自定义解析逻辑。