Hibernate Search是在apache Lucene的基础上建立的主要用于Hibernate的持久化模型的全文检索工具。像Lucene这样的检索引擎能够给我们的项目在进行检索的时候带来非常高的效率,但是它们在基本对象的检索时会有一些问题,比如不能实现检索内容跟实体的转换,Hibernate Search正是在这样的情况下发展起来的,基于对象的检索引擎,能够很方便的将检索出来的内容转换为具体的实体对象。此外Hibernate Search能够根据需要进行同步或异步的索引更新。 http://baike.baidu.com/view/6288294.htm
View DetailsJasperReport是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF,HTML,或者XML格式。该库完全由Java写成,可以用于在各种Java应用程序,包括J2EE,Web应用程序中生成动态内容。 jasperreport是开源的,这给我们带来很大方便,但是文档却要钱,让人不爽。不过人总要生存,再说,做这么一个好东西,用户总不能一点代价也不付(虽然对于中国普通程序员来说太贵了点)。它还有一个相关的开源工程IReport,这是一个图形化的辅助工具,因为JasperReport仅提供了可使用的类库而未提供更好的开发工具,IReport的出现解决了这一难题。它们配合使用将会更大程度的提高效率。 该库完全由Java写成,可以用于在各种Java应用程序,包括J2EE,Web应用程序中生成动态内容。它的主要目的是辅助生成面向页面的(page oriented),准备付诸打印的文档。JasperReport借由定义于XML文档中的report design进行数据组织。这些数据可能来自不同的数据源,包括关系型数据库,collections,java对象数组。通过实现简单的接口,用户可以将report library插入到订制好的数据源中,在以后我们将提到有关内容。 其实这是一份JasperReport Ultimate Guide的简单翻译以及我的理解和例子。在最后,我将描述一个我正在做的工程,将其中用到的相关信息贡献出来。我这么做是因为当我在学这个类库的时候苦于很少有相关的中文文档,又或语言不详,希望其他人不再受苦。这个文档将分几次贴出来,与原文档的章节相对应。这份文档的Word形式将在全部完成之后放在我的公开邮箱中与各位共享。 http://baike.baidu.com/view/1662522.htm
View Details数据库管理工具 基本内容 DbVisualizer是一个完全基于JDBC的跨平台数据库管理工具,内置SQL语句编辑器(支持语法高亮),凡是具有JDBC数据库接口的数据库都可以管理,已经在Oracle, Sybase, DB2, MySQL, InstantDB, Cloudcape, HyperSonic ,Mimer SQL上通过测试。 DbVisualizer常见问题解答:http://database.ctocio.com.cn/tips/484/7625484.shtml DbVisualizer是一款涉及到所有主要数据库且基于交叉平台上的援助与维护数据库工具。它允许通过JDBC的驱动同时连接各种不同的数据库;立刻指向并浏览数据库结构,观看数据库对象的详细特征,图解桌面数据、任意的SQL声明或SQL脚本,利用逆向工程图示出primary/foreign的键值,并以先进的图表方式显示出来,友好的图形界面接口与各种特色的独特组合,足以值得您去收藏一份。 DbVisualizer 是一个功能强大Java工具,用来同时查看一个或者多个JDBC击活的数据库。它可以以图形的方式显示表单之间的关系。它可以显示关于数据项、关键字等信息。使用SQL命令,还可以执行所有的SQL语句。 个人版和免费版本相比,个人版有以下功能扩展: #编辑表格数据。 #支持表格/索引创建。 #SQL脚本执行。 #多个结果集合管理。 #数据图表化。 #BLOB/CLOB数据管理。 #浏览存储步骤等。 DbVisualizer的管理方式确实比phpMyAdmin会强一些,特别是可以轻松生成E-R图并导出,确实是不错的软件,现在只有英文版,DbVisualizer中文版还没有出,期待中文版。 DbVisualizer使用JAVA开发的,目前拿他来做Oracle、MySQL、PostgreSQL甚至包括 MS SQL Server 数据库管理都是一件非常轻松的事情。 新版本已经集成了JDBC 的jar包,所以在安装6.0版本时要选中JDBC 的jar包,不然在创建与数据库连接时无法连接的。 这是我在偶然间找到的一个软件,它是使用JAVA开发的,可以这么说,只要有 JDBC 的驱动包,可以连接市面上所有的数据库。目前经我测试,已经连接上 Oracle、SyBase、MySQL、PostgreSQL。 破解方法: Unpack, Install. Copy cracked files from /iNViSiBLE dir to installdir\lib Run app, go to Help > License Key and select supplied license file. http://baike.soso.com/v26476145.htm
View Details*.testsettings文件; 在VS 2010中,测试解决方案会自动产生两个文件。一个是TraceAndTestImpact.testsettings,记录用于调试的测试设置。另一个Local.testsettings为本地缺省的测试设置。VS2008只有本地缺省设置。 *.testsettings,这是运行测试的环境参数和运行参数,包括以下内容:a) 用例运行前后执行的脚本b) 是否启用数据分析(代码覆盖率,测试影响分析,模拟网络,录制视频,智能跟踪等等)很多功能都是VS2010独有的,c) 运行机器是本机还是远程机器d) 测试超时时间等 VS2010 增强了测试监控功能,例如智能跟踪(IntelliTrace)和视频录制(Video Recoder),测试影响分析(TestImpact)等等 *.vsmdi文件,用于管理测试用例的列表(Test List).*.vsmdi 文件是管理Test List的,在VS 2010中虽然支持,但不推荐使用。主要原因是*.vsmdi非常不灵活,很难集中维护。取而代之的是更加自然的测试分类(Test Category):通过给每个测试用例设置标签,运行的时候通过标签选择需要运行的测试用例。 为了兼容问题,VS2010 还是支持*.vsmdi。下面是*.vsmdi的一些基本格式。 其内容基本上包括一个树状内容的Test List 列表,各个节点通过ParentListID相连,其中包括一个特殊根节点。另外,在每个TestList中,一个TestLink代表一个测试用 例,TestLink的ID是通过测试方法名,测试类名和包名等,通过MD5计算而得(而非任意值),我以前就写过一个程序,自动生成*.vsmdi文 件。 如何设置不同的标签,在运行用例时,可以通过过滤标签的属性来运行。其方法如下: 步骤一: 为每个测试用例设置测试分类属性(Test Category),在方法的属性中增加。
1 2 3 4 |
<strong style="padding:0px;margin:0px;">[<span style="padding:0px;margin:0px;color:#2b91af;">TestCategory</span>(<span style="padding:0px;margin:0px;color:#a31515;">"Nightly"</span>), <span style="padding:0px;margin:0px;color:#2b91af;">TestCategory</span>(<span style="padding:0px;margin:0px;color:#a31515;">"Weekly"</span>)</strong>, <span style="padding:0px;margin:0px;color:#2b91af;">TestMethod</span>()] <span style="padding:0px;margin:0px;color:blue;">public void </span>TestMethod1() { <span style="padding:0px;margin:0px;color:green;">// // TODO: Add test logic here // </span>} |
步骤二: 通过测试分类,运行测试用例 1)从UI中,选择测试用例运行 2)通过命令行运行 mstest /testcontainer:MyTestprojectName.dll /category:"Nightly&Weekly" 在条件选择时候,可以使用&或则|作为操作条件;但是在VS2010中,只能用一种操作符号 运行测试 写好测试用例就可以运行,Ctrl F5,就这么简单,能够得到测试用例运行的结果。很容易在IDE看到,测试结果,那么如何读懂后面的文件呢? 一次测试运行结果的目录: *.trx文件. 运行结果目录。其中有In, Out 和每个TestCase的详细结果。 http://opheliawei.blog.51cto.com/2653343/1026956
View Details你应该看过一些如《关于调试的N件事》这类很流行的帖子 。假设我每天花费1小时在调试我的应用程序上的话,那累积起来的话也是很大量的时间。由于这个原因,用这些时间来重视并了解所有使我们调试更方便的功能。那能为你省下一些时间,也将会使你的生活更安逸、轻松。同时也表明其它关于此主题的帖子也是很有价值的。 第1条:不要调试太多 一个关于调试的疯狂声明作为开头。但它必须是要说的!尝试切分一下你那复杂的逻辑成多个独立的单元,并编写单元测试来检测你代码的正确性。我想像如下这样的流程应该是发生得非常频繁的—-一些人通过大型web应用程序点击、填写多个表单、切换到不同的页面、正在最后的页面上检测工个计算逻辑和实现这个调试视图中的大部分逻辑。在启动你的tomcat之前总是问你自己:有没有方法使用一个单元测试来检测这些行为?你在过去这些时间可以不知道或已忘记这些,但从现在开始,我们将要关注一些eclipse的调试技巧,你会发现有大量的关于良好代码设计的好东西。 zhouao翻译于 2天前 0人顶 顶 翻译的不错哦! – 断点视图 : 条件断点 如果你只对应用中的某部分感兴趣的话,这个功能非常有用。例如,如果你要在第13次循环的时候检查程序,或者在一个抽象父类中调试某些功能,而你只关注其中一个具体的实现。你可以在断点视图中设置条件,或者通过代码旁边的蓝色断点标记的右键菜单("Breakpoint Properties")设置。你可以在条件代码片段为true的时候暂停程序,或者当代码片段的值改变的时候挂起程序。 enixyu翻译于 昨天(8:45) 0人顶 顶 翻译的不错哦! 其它翻译版本(1) – 变量视图:展示逻辑结构 如果你需要在变量视图查看一个Map对象或者List对象的值,对于eclipse的默认设置,一般并不是那么容易。假设,你使用的是HashMap,你需要点击遍历各个实体条目,并面临各种HashMap的实现细节。但是,在变量视图上面有一个叫做“Show Logical Structure”的按钮。它非常有用,尤其当你的对象的toString()方法所展示的信息并不友好的时候。我的老大在几周前为我展示了这个功能。你知道,他经常跟PowerPoint或者Excel打交道。对于我这么一个开发人员,多丢脸哦 未开启“Show Logical Structure” 开启“Show Logical Structure” enixyu翻译于 昨天(8:54) 0人顶 顶 翻译的不错哦! – 变量视图:更改变量值… 当你需要稍微更改输入信息的时候,不需要重新开始调试会话,只需在一个表格中输入新的信息,你可以在调试阶段直接修改你的变量的值。有写时候,你可以节省一些时间,你可以通过这个功能,更加简单的模拟一些怪异的情况。 – Display视图 你知道“Display视图”吗?你可以在调试过程中,通过“Window” -> “Show View” -> “Display”来激活它。现在,你的eclipse应该是一个空白的新视图。你可以使用这个视图,输入或者演算一些新的代码。这些代码在当前的调试位置的上下文环境中被执行,这意味着,你可以使用所有变量甚至是内容助手。要执行你的代码的话,只需标记它,并使用右键菜单或者CTRL+U(执行)或者 CTRL+SHIFT+I (检查). enixyu翻译于 昨天(9:02) 0人顶 顶 翻译的不错哦! – 导航: Drop to Frame 我想任何人都知道“Step Into”, “Step over”,而且可能也知道“Step return”. 这些是调试时的基本导航功能。我想提两个我非常喜欢的导航的高级方法。第一个是“Drop to Frame”. 使用这个特性你可以及时回退 你可以直接回退到运行过的java堆栈帧中某一帧。当我调试时,一不小心错过了某个关注的代码行时,我常常用这个回退一帧。使用“Drop to Frame”这个特性我可以简单的重新运行某帧代码。 – 导航: Step into Selection 第二个是“Step into Selection”. 这也是很简单,但很多人使用的一个。要使用它,你只需要按 Ctrl+Alt 同时点击一个你想运行到的方法名。非常方便,非常快速。相比“Step Into”这个非常方便,想想你像跟踪进一个有很多参数的函数,如果用“Step Into”你必须进入,退出每个参数计算过程,才能进入到你真正想进的函数。“Run to line”也是很棒的特性。只需要把光标放在你想运行到的哪一行前面,然后按“CTRL+R”就可以了。 ljb_iss翻译于 […]
View Details今天在eclipse里报这个错误: Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead. Please fix project properties 1. 项目 右键 ->android tools ->Fix Project 2. 如果不可以,检查Project -> Properties->Java Compiler 确认JDK compliance被设置为1.6,并且enable specific seetings. http://www.cnblogs.com/sunjialiang/archive/2011/08/25/2152715.html
View Details这次我了解了WPF的多线程大致实现原理,并简单编写了一个多线程程序。 先将几个常用的概念列一下: 线程关联度:WPF属于创建它的线程,并且不能被其他的线程直接访问。当一个对象被关联到一个单线程时,就认为它是一个单线程对象,并且认为该对象具有线程关联度。 同步:同步可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。 这样的好处是能避免读写时的数据错误。 异步:执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程。在此期间可以进行别的过程,当系统接收到之前那个调用的返回值或消息时,系统会自动触发委托,开始处理返回值。 下面以两段WPF的代码为例,说明如何利用委托来实现异步线程,我使用的是Visual Studio 2008 第一段代码 前台代码 <Window x:Class="ThreadTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> <Border Width="200" Height="225" BorderBrush="Black" BorderThickness="1" Margin="4"> <StackPanel> <TextBox Height="19" Name="textBox1" VerticalAlignment="Top" /> <Button HorizontalAlignment="Left" Name="button1" Width="75" Click="button1_Click">Button1</Button> <Button HorizontalAlignment="Left" Name="button2" Width="75" Click="button2_Click">Button2</Button> <Label Height="28" Name="UIThreadId" Width="120" Content=""/> […]
View Details数据绑定和服务器控件模板互为补充,数据绑定用于从数据库中提取数据,而上一章说的服务器控件模板是将这些数据以一定的格式显示在网页中,对于大多数网站来说,根据内容生成特定的html非常常见,而对于开发人员来说,从数据库中提取出数据再以一定的格式显示到网页上是经常需要完成的工作,而这些大多都利用GridView,Repeater等控件的数据绑定功能。 一个典型的过程如下图: 控件的数据绑定 数据绑定有几种不同的形式,对于简单的数据绑定来说,仅仅是将一个数据表达式求值并将该值赋给某个属性,比如下面代码: <asp:Labelid="MyLabel"runat="server"Text="<%= MyDataBoundMethod() %>/> 这段代码是将一个函数的返回值最为label的Text属性. 而对于另外一些较为复杂的数据绑定控件来说,数据绑定意味着一大堆的数据以迭代的形式来帮定到一大堆的控件上来生成html.比如GridView会以Table的形式展现数据。而每一行<tr>内部用于格式的HTML会相同,而内容则有差异. 数据绑定控件的基类 和前面说的一样,在控件开发时选择合适的类作为基类是很重要的,而支持数据绑定的基类主要是从下面几个基类中去进行选择: System.Web.UI.WebControls.DataBoundControl:这个类是所有数据绑定类的基类。 System.Web.UI.WebControls.CompositeDataBoundControl:这个类继承于DataBoundControl基类,用于复合服务器绑定控件 System.Web.UI.WebControls.HierarchicalDataBoundControl:基于树的分层控件的基类 在asp.net中,默认的数据绑定控件分布如下图: 而用更清晰一些的视图来表示几个数据绑定基类之间的关系是: 上面几个基类中,重写了DataBind方法(最开始是定义在Control当中),使DataBind调用PerformSelect,该方法能够检索有效的数据集合以使绑定发生。该方法是受保护的,因为它包含实现细节;它是抽象的,因为它的行为只能由派生类实现。 如果不是基于IDataSource(比如那些SqlDataSource,也就是通过DataSourceID属性来定义的)来获取数据,PerformSelect方法内部会执行GetData方法来获取数据,而在调用GetData方法之前,会触发OnDataBinding事件。而之后则会触发DataBound事件 下面是MSDN中PerformSelect的源码: protected override void PerformSelect() { // Call OnDataBinding here if bound to a data source using the // DataSource property (instead of a DataSourceID), because the // databinding statement is evaluated before the call to GetData. if (! IsBoundUsingDataSourceID) { OnDataBinding(EventArgs.Empty); } // The GetData method retrieves the DataSourceView object from // the IDataSource associated with the data-bound control. GetData().Select(CreateDataSourceSelectArguments(), OnDataSourceViewSelectCallback); // The PerformDataBinding method has completed. RequiresDataBinding = false; MarkAsDataBound(); // Raise the DataBound event. OnDataBound(EventArgs.Empty); } 从代码中可以看出GetData利用OnDataSourceViewSelectCallback回调来调用PerformDatabinding方法,而PerformDataBinding方法又利用CreateControlHierarchy方法来构建子控件。在调用过CreateControlHierarchy方法后,这个方法会将空间内部的ChildControlIsCreated属性设置成True,从而数据绑定控件不会继续调用CreateChildControl来防止子控件被重复创建,如下是OnDataSourceViewSelectCallback和PerFormDataBinding的源码: privatevoid OnDataSourceViewSelectCallback(IEnumerable retrievedData) { // Call OnDataBinding only if it has not already been // called in the PerformSelect method. if (IsBoundUsingDataSourceID) { OnDataBinding(EventArgs.Empty); } // The PerformDataBinding method binds the data in the // retrievedData collection to elements of the data-bound control. PerformDataBinding(retrievedData); }} protectedoverridevoid PerformDataBinding(IEnumerable data) { base.PerformDataBinding(data); Controls.Clear(); ClearChildViewState(); TrackViewState(); if (IsBoundUsingDataSourceID) CreateControlHierarchy(true, true, data); else CreateControlHierarchy(true, false, data); ChildControlsCreated = true; } CreateChildControls方法一般用于创建组合控件。在此方法中可以定义自己需要的控件,进行实例化和赋值等,并将其添加到当前Controls集合中。数据绑定的生成方式和用此方法的方式的不同之处可用下图表示: 1-5是数据绑定方式,而6-9是利用CreateChildControls方法来进行创建 http://www.cnblogs.com/CareySon/archive/2009/10/29/1591807.html
View Details在Asp.net 2.0以后的版本,Asp.net提供了服务器控件模板(Template)和数据绑定(Data Bind)来简化开发工作,模板是是用于定制化服务器控件或者HTML如何在页面呈现,而模板和数据绑定往往结合起来在一起实现更高级的功能,比如最经典的GridView.例如,在 GridView服务器控件中可以使用 HTML 元素和控件的组合来创建列表中每行的布局。同样,GridView服务器控件对网格中的每行都具有一个默认的外观。但是,您可以通过为单个行、间隔行、所选行等行定义不同的模板来自定义网格的外观。 定制控件内容 模板用于让开发人员自定义HTML或者服务器控件作为主要控件输出流的一部分。提供了模板的服务器控件其实是给予插入自定义内容提供了容器。 服务器控件模板的强大之处在于它通过让开发人员可以定制输出特定的html来给予了开发人员极高的灵活性.如下图: 使用服务器控件模板 使用服务器控件模板的一大好处是我们可以专注开发空间,而把外观等html和css设置内容让其他人来完成。 在GridView控件里,我们可以通过在ItemTemplate里设置任何我们想设置的内容,在DropDownList控件中我们可以插入ListItem子控件,但在里面插入比如TextBox控件则不行。这个原因就要说到下面一个标签(Attribute) ParseChildren Attribute 服务器控件必须通过在类声明时添加ParseChildren标签来告诉asp.net页面分析器这个控件需要支持模板。ParseChildren的功能是让服务器控件所含有的子控件作为它的一个属性存在。 对于继承System.Web.UI.WebControls.WebControl基类的控件,这个标签已经通过继承而存在不需要再声明 ParseChildren标签还暴露了ChildrenAsProperties属性,在使用 可以:ParseChildrenAttribute(ChildrenAsProperties = true) 也可以用简便写法:ParseChildren(true) ChildrenAsProperty属性的作用是让控件的属性和直接在控件内部的html代码,或者说是XML代码(“<”和”>”)进行匹配.如下图: 而不使用ChildrenAsProperties属性的则会是如下图: 下面通过一个Demo来看 Demo 服务器导航菜单 先看Demo的效果 先声明两个用于存放子控件的容器,代码如下: publicclassBasicTemplateContainer : WebControl, INamingContainer { public BasicTemplateContainer(): base(HtmlTextWriterTag.Div) { this.BorderWidth = 1; this.BorderStyle = BorderStyle.Solid; } } publicclassSeperatorTemplateContainer : WebControl, INamingContainer { public SeperatorTemplateContainer(): base(HtmlTextWriterTag.Span) { } } 第一个用于存放HeaderTemplate和footerTemplate,而第二个用于存放分隔符 再声明一个存放菜单超链接的容器,代码如下: [TypeConverter(typeof(ExpandableObjectConverter))] publicclassMenuItemData { public MenuItemData() { } [NotifyParentProperty(true)] publicstring Title { get; set; } [NotifyParentProperty(true)] publicstring Url { get; set; } [NotifyParentProperty(true)] publicstring ImageUrl { get; set; } [NotifyParentProperty(true)] publicstring Target { get; set; } } 最后声明一个继承于CompositeControl基类的控件,声明代码如下: publicclassTemplateMenu : CompositeControl 最终完全代码如下: TemplateMenu完全代码 1using System; 2using System.Web; 3using System.Web.UI; 4using System.Web.UI.WebControls; 5using System.Collections; 6using System.ComponentModel; 7using System.Web.UI.WebControls; 8namespace bindcontrol 9{ 10 [ToolboxData("<{0}:templatemenu runat=server></{0}:templatemenu>")] 11publicclass TemplateMenu : CompositeControl 12 { 13private ArrayList menuData; 14public TemplateMenu(): base() 15 { 16 menuData =new ArrayList(){ 17 18new MenuItemData{Title="博客园", Url="http://www.cnblogs.com"}, 19new MenuItemData{Title="Microsoft", Url="http://www.microsoft.com"}, 20new MenuItemData{Title="ASP.Net", Url="http://asp.net"}}; 21 } 22private ITemplate headerTemplate; 23 [Browsable(false), Description("The header template"), 24 PersistenceMode(PersistenceMode.InnerProperty), 25 TemplateContainer(typeof(BasicTemplateContainer))] 26public ITemplate HeaderTemplate 27 { 28get 29 { 30return headerTemplate; 31 } 32set 33 { 34 headerTemplate = value; 35 } 36 } 37private ITemplate footerTemplate; 38 [Browsable(false), Description("The footer template"), 39 PersistenceMode(PersistenceMode.InnerProperty), 40 TemplateContainer(typeof(BasicTemplateContainer))] 41public ITemplate FooterTemplate 42 { 43get 44 { 45return footerTemplate; 46 } 47set 48 { 49 footerTemplate = value; 50 } 51 } 52private ITemplate separatorTemplate; 53 [Browsable(false), Description("The separator template"), 54 PersistenceMode(PersistenceMode.InnerProperty), 55 TemplateContainer(typeof(SeperatorTemplateContainer))] 56public ITemplate SeparatorTemplate 57 { 58get 59 { 60return separatorTemplate; 61 } 62set 63 { 64 separatorTemplate = value; 65 } 66 } 67privatevoid CreateControlHierarchy() 68 { 69if (HeaderTemplate !=null) 70 { 71 BasicTemplateContainer header =new BasicTemplateContainer(); 72 HeaderTemplate.InstantiateIn(header); 73 Controls.Add(header); 74 } 75int count = menuData.Count; 76for (int index =0; index < count; index++) 77 { 78 MenuItemData itemdata = (MenuItemData)menuData[index]; 79 HyperLink link =new HyperLink() 80 { 81 Text = itemdata.Title, 82 NavigateUrl = itemdata.Url, 83 ImageUrl = itemdata.ImageUrl, 84 Target = itemdata.Target 85 }; 86 Controls.Add(link); 87if (index != count –1) 88 { 89if (SeparatorTemplate !=null) 90 { 91 SeperatorTemplateContainer separator =new SeperatorTemplateContainer(); 92 SeparatorTemplate.InstantiateIn(separator); 93 Controls.Add(separator); 94 } 95else 96 { 97 Controls.Add(new LiteralControl(" | ")); 98 } 99 }100 }101if (FooterTemplate !=null)102 {103 BasicTemplateContainer footer =new BasicTemplateContainer();104 FooterTemplate.InstantiateIn(footer);105 Controls.Add(footer);106 }107 }108overrideprotectedvoid CreateChildControls()109 {110 Controls.Clear();111 CreateControlHierarchy();112 }113publicoverride ControlCollection Controls114 {115get116 {117 EnsureChildControls();118returnbase.Controls;119 }120 }121 }122123publicclass BasicTemplateContainer : WebControl, INamingContainer124 {125public BasicTemplateContainer(): base(HtmlTextWriterTag.Div)126 {127this.BorderWidth =1;128this.BorderStyle = BorderStyle.Solid;129 }130 }131publicclass SeperatorTemplateContainer : WebControl, INamingContainer132 {133public SeperatorTemplateContainer(): base(HtmlTextWriterTag.Span)134 {135 }136 }137 [TypeConverter(typeof(ExpandableObjectConverter))]138publicclass MenuItemData139 {140public MenuItemData()141 {142 }143 [NotifyParentProperty(true)]144publicstring Title { get; set; }145 [NotifyParentProperty(true)]146publicstring Url { get; set; }147 [NotifyParentProperty(true)]148publicstring ImageUrl { get; set; }149 [NotifyParentProperty(true)]150publicstring Target { get; set; }151 }152} 前台调用代码如下: 首先注册控件:<%@Register Namespace="bindcontrol"TagPrefix="dd"%> 然后是前台代码: <dd:TemplateMenurunat="server"> <HeaderTemplate>template header</HeaderTemplate> <SeparatorTemplate>%</SeparatorTemplate> <FooterTemplate>template footer</FooterTemplate> </dd:TemplateMenu> 注意,作为模板的类型必须声明成ITemplate类型,而这个ITemplate的具体类型则通过TemplateContainer标签进行注入.我们通过声明CreateControlHierarchy()函数来进行控制控件的具体输出,最后通过覆盖父类的CreateChildControls()方法来调用我们写好的CreateControlHierarchy方法达到控制输出的目的。 最后,你可能有疑问,那个神奇的ChildrenAsProperties属性跑哪去了?如果没有这个属性,那上面<headerTemplate>之类的标签又是如何匹配的呢?还记得吗,继承与WebControl基类的控件继承了这个标签,所以不用显示声明,所以ChildrenAsProperties属性come for free:-) http://www.cnblogs.com/CareySon/archive/2009/10/19/1586146.html
View Details