< li > <%= Html.ActionLink( " Account " , " List " , " Account " ) %></ li > < li > <%= Html.ActionLink( " AttachAccount " , " List " , " AttachAccount " ) %></ li > < li > <%= Html.ActionLink( " ChildClass " , " List " , " ChildClass " ) %></ li > < li > <%= Html.ActionLink( " PrimaryClass " , " List " , " PrimaryClass " ) %></ li > < li > <%= Html.ActionLink( " Expense " , " List " , " Expense " ) %></ li > < li > <%= Html.ActionLink( " Income " , " List " , " Income " ) %></ li > < li > <%= Html.ActionLink( " TranferAccount " , " List " , " TranferAccount " ) %></ li > < li > <%= Html.ActionLink( " Member " , " List " , " Member " ) %></ li >
10、编译,运行,增加一些数据,或者下载我的数据库备份: 。 [修改代码] 好,以上的程序都能正常运行,现在来看这个模块: (前面的19374端口可能有变,自己修改) 输入ChildClassName和PrimaryClassID,很显然,这里的PrimaryClassID不够人性化,还不能做到Html下拉框的方式。 于是我们作如下修改: 1)在Models中增加类文件ChildClassViewData.cs,里面包含两个类:ChildClassEditViewData和ChildClassNewViewData,代码如下: namespace AccountBook.Models { public class ChildClassEditViewData { public ChildClassInfo ChildClass { get; set; } public List<PrimaryClassInfo> PrimaryClassList { get; set; } } public class ChildClassNewViewData { public List<PrimaryClassInfo> PrimaryClassList { get; set; } } }
2)然后打开 ChildClassController.cs,修改其中的Add()方法为: public void Add() { ChildClassNewViewData viewData = new ChildClassNewViewData(); viewData.PrimaryClassList = DBContext.GetPrimaryClassList(); RenderView("Add", viewData); }
这里是获取了PrimaryClassList,保存在ChildClassNewViewData的实例中,然后RenderView到Add.aspx,这样,在Add.aspx.cs中,页面继承自ViewPage<ChildClass>必须修改为 ViewPage<ChildClassNewViewData>,这样在Add.aspx这个视图部分,ViewData代表的就是强类型的ChildClassNewViewData对象。 3)打开Views/ChildClass/Add.aspx,可以看到,提供输入PrimaryClassID的是一个 <input type="text"......>: < input type = " text " name = " PrimaryClassID " id = " PrimaryClassID " value = " <%= Item.PrimaryClassID%> " />
现在我们就可以将其修改为: <%= Html.Select( " PrimaryClassID " , ViewData.PrimaryClassList) %>
使用的是HtmlHelp中的Select重载方法来绑定下拉框。“PrimaryClassID”是控件名称,第二个参数是数据源。 同样,在Views/ChildClass/Edit.aspx中,我们同样将相关代码 < input type = " text " name = " PrimaryClassID " id = " PrimaryClassID " value = " <%= Item.PrimaryClassID%> " />
替换为如下: <%= Html.Select( " PrimaryClassID " , Item.PrimaryClassList, Item.ChildClassInfo.PrimaryClassID) %>
在Edit.aspx页面,显示出当前ChildClass所对应的PrimaryClassID,也是以下拉框的形式表示,同时默认选择PrimaryClassID对应的PrimaryClassName,各参数含义同上,第三个参数就是默认选择的PrimaryClassID。 4)好,现在打开Views/ChildClass/List.aspx页面,显示了当前所有ChildClass,我们看下这部分的代码: < h2 > ChildClass List <%= Html.ActionLink( " Add " , " Add " ) %> </ h2 > <% AccountBookTest.Models.ChildClassList Lst = ViewData; %> <% if (ViewContext.TempData[ " msg " ] != null ) { %> <p><%=ViewContext.TempData["msg"] %></p> <% } %> < form > < table > < tr > < td >< strong > ChildClassName </ strong ></ td > < td >< strong > PrimaryClassID </ strong ></ td > </ tr > <% foreach (AccountBookTest.Models.ChildClass item in Lst) %> <% { %> <tr> <td><%=item.ChildClassName.ToString()%></td> <td><%=item.PrimaryClassID.ToString()%></td> <td><%=Html.ActionLink("Edit","Edit",new {id = item.ChildClassID})%></td> <td><%=Html.ActionLink("Delete","Delete", new {id = item.ChildClassID})%></td> </tr> <%} %> </ table > < p ></ p > </ form >
可以看到,有一个很亲切的c#代码foreach语句出现,它的作用是循环当前的 AccountBookTest.Models.ChildClassList Lst,逐一显示ChildClass的信息:ChildClassName,PrimaryClassID以及两个可选操作Edit和Delete。 现在我们进行如下修改: < h2 > ChildClass List <%= Html.ActionLink( " Add " , " Add " ) %> </ h2 > <% AccountBook.Models.ChildClassList Lst = ViewData; %> <% if (ViewContext.TempData[ " msg " ] != null ) { %> <p> <%=ViewContext.TempData["msg"] %></p> <% } %> < table > < tr > < td > < strong > ChildClassName </ strong > </ td > < td > < strong > PrimaryClass </ strong > </ td > < td > < strong > Edit </ strong > </ td > < td > < strong > Delete </ strong > </ td > </ tr > < asp:Repeater ID = " AllChildClass " runat = " server " onitemdatabound = " AllChildClass_ItemDataBound " > < ItemTemplate > < tr > < td > <% # Eval( " ChildClassName " ) %> </ td > < td > <% # Eval( " PrimaryClassID " ) %> </ td > < td > < asp:HyperLink ID = " hlEdit " runat = " server " > Edit </ asp:HyperLink > </ td > < td > < asp:HyperLink ID = " hlDelete " runat = " server " > Delete </ asp:HyperLink > </ td > </ tr > </ ItemTemplate > </ asp:Repeater > </ table >
用一个服务器端控件Reapter绑定ChildClassList.因此,List.aspx.cs中的代码修改为如下: public partial class ChildClassListView : ViewPage < ChildClassList > { protected System.Web.UI.WebControls.Repeater AllChildClass;//这里居然要声明下控件(下同),否则在codefile中无法访问Reapter控件?困惑! protected System.Web.UI.WebControls.HyperLink hlEdit; protected System.Web.UI.WebControls.HyperLink hlDelete; public void Page_Load() { AllChildClass.DataSource = ViewData;//这里绑定的数据源就是ChildClassList实例对象。 AllChildClass.DataBind(); } protected void AllChildClass_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { ChildClassInfo childClassInfo = (ChildClassInfo)e.Item.DataItem; HyperLink hlEdit = (HyperLink)e.Item.FindControl("hlEdit"); HyperLink hlDelete = (HyperLink)e.Item.FindControl("hlDelete"); hlEdit.NavigateUrl = "http://www.cnblogs.com/ChildClass/Edit/" + childClassInfo.ChildClassID; hlDelete.NavigateUrl = "http://www.cnblogs.com/ChildClass/Delete/" + childClassInfo.ChildClassID; } } }
现在 我的问题来了: 1)页面上使用的服务器端控件Reapter,在CodeFile中居然必须声明,否则无法识别,为什么会这样?所有服务器控件都必须声明,我之前看的一个例子就没有,怎么回事?麻烦各位帮我找找原因。 [2008.04.17晚回答]在解决方案上右键——>Convert to Web Applications就可以把解决方案变成Web Application的形式。这一个Convert其实就是给每个页面(比如Test.aspx)增加对应的Test.designer.cs的文件,然后页面上的控件的声明全部放在这里。其实这个答案应该早就想到,只是太专注于MVC,反而忘了根本的web Application文件结构。 2)在修改之前的页面代码中的foreach语句,可以使用 <%=Html.ActionLink("Edit","Edit",new {id = item.ChildClassID})%>来很方便很直接地放置一个Edit链接,链接地址是ChildClass/Edit/[ ChildClassID], 现在问题是,我使用了Reapter控件直接绑定数据源之后,怎样才可以类似 <%=Html.ActionLink("Edit","Edit",new {id = item.ChildClassID})%>这样的写法,直接生成一个Edit的链接呢?疑惑在于,在Reapter中无法把[ ChildClassID]传到 <%=Html.ActionLink("Edit", "Edit", ……)%>中的"……"中。 怎么办?我暂时只能采用webForm的做法,在ItemBound事件中动态绑定......那请问,是我的做法有错误还是本身就不能通过服务器控件绑定的方式来动态生成Edit按钮? ps:Delete的也是同样问题。 3) 2008.04.17补充一个问题:显示ChildClass信息的时候,由于Model.ChildClassInfo中仅有PrimaryClassID属性 ,但如果要显示出PrimaryClassID对应的PrimaryClassName,那该如何实现?在Model.ChildClassInfo中增加PrimaryClassName属性??还是在Controllers中进行匹配?补充:这其实是类设计的范畴,和mvc没多大关系的。 总结:今天的blog就写这些内容,就是ChildClass的Add和Edit,以及List的显示。同时提了 三个问题,留给大家帮我解决。 本文最新Demo下载地址是: 以及数据库的备份(含数据):