以前一直在用 DetailsView 来做后台添加、修改功能,一个页面就现实了两大管理功能。如果不用它,自己拖控件来写是很麻烦的,还要排版呢!
我来讲讲这样做的好处吧:
1、后台界面通过主题可以很好控制
2、由于后台管理的功能性文件减少,维护也显示得更方便
3、逻辑还算好控制吧,可以现实大多数添加/修改界面及功能
缺点:
1、编辑模板时比较麻烦
2、一定要开启 ViewState
基础知识:
DetailsView 有 ItemInserting 或 ItemUpdating 事件,有四种模式,分别是 Insert,Edit,Select,Delete,只说 Insert 与 Edit 模式
先看 ItemInserting 事件,事件由 DetailsView 的插入按钮点击触发,DetailsViewInsertEventArgs.Values 以字典的方式保存了模板中绑定的数据。
如果 DetailsView 有以下代码:
这里只拿 BoundFields 来举例,如果使用模板 <TemplateField>,则需要输入 <%# Bind("Name") %> 来绑定一个 WebControl。
甚至可以 Bind 一个 asp:Label.Text,绑定 asp:Label.Text 的话一般是想此字段为只读(不可编辑)
- <asp:detailsview ID="DetailsView1" runat="server" DefaultMode="Insert">
- <Fields>
- <asp:BoundField DataField="Name" HeaderText="名称" />
- </Fields>
- </asp:detailsview>
如果将某一字段的 InsertVisible 设置为 false,则 DetailsView 在 Insert 模式下不会显示该字段。
在 ItemInserting 事件中,使用 e.Values["Name"] 得到 Name 的值,与模板中的绑定类型一值。
ItemUpdating 事件中,e.NewValues 和 e.OldValues 参数,顾名思义!!
默认情况下 DetailsView 一定要设置 DataSource 或 DataSourceID 后,触发这两个事件时 e.Values 才会有值!不然,即时触发了 ItemInserting 事件,数据都不会经 e 传入方法中。。。。但是我并不想使用 DataSource 和 DataSourceID 属性,我想自己在 ItemInserting 写插入操作。
经过 Reflector 分析 DetailsView 后,我们只需要重构一下 DetailsView 即可,代码如下:
- public class MyDetalsView : DetailsView {
- public override string DataSourceID {
- get { return string.IsNullOrEmpty(base.DataSourceID) ? "null" : base.DataSourceID; }
- set { base.DataSourceID = value; }
- }
- protected override IDataSource GetDataSource() {
- return null;
- }
- }
修改功能时需额外写多一个事件,ItemUpdated 里将 e.Exception = true,不然 DetailsView 验证数据时会报错!
最后在 Page_Load 事件中写上以下代码:
- if (!PostBack) {
- if (找到对象) {
- DetaisView1.DataSource = new 对象类[] { 对象 };
- DetailsView1.DataBind();
- }
- else {
- 找不到记录时,将模式设置为插入!
- DetaisView1.ChangeMode(DetailsViewMode.Insert);
- }
- }