转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 站长学院 >> Web开发 >> 正文
Mastering ASP.Net DataBinding         ★★★★

Mastering ASP.Net DataBinding

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1929 更新时间:2009/4/23 10:44:25
>Notice that our previously code-cluttered ItemTemplate is now considerably cleaner - this is because we''''ve pushed the logic to the itemDataBoundRepeater_ItemDataBound function in codebehind:
   1:  protected void itemDataBoundRepeater_ItemDataBound(object source, RepeaterItemEventArgs e) {
   2:   if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item){
   3:    Literal lit = (Literal)e.Item.FindControl("see");
   4:    if (lit != null){
   5:     Owner owner = (Owner)e.Item.DataItem;
   6:     if (owner.Pets.Count == 0){
   7:      lit.Text = "no pets";
   8:     }else{
   9:      lit.Text = "see pets";
  10:     }
  11:    }
  12:   }
  13:  }
Since we are dealing with repeaters, e.Item returns a reference to the current RepeaterItem. If this was a datalist, it would return a reference to a DataListItem, or a DataGridItem if it were a datagrid. For the most part however, all three provide the same capabilities. The first thing to do is check the ItemType and make sure we are currently dealing with an AlternateItem or an Item [2]. Next get a reference to our literal [3], this is an extremely powerful capability which allows us to really keep our UI clean. As we saw in a previous section, we can cast DataItem directly to the individual item being bound (in this case Owner, but again, if we bound to a dataset, it would be a DataRowView) [5]. Finally all the pieces are in place to apply our presentation logic [6-10].

An alternative to using e.Item.FindControl() is to refer to the controls by position via e.Item.Controls[INDEX]. While this may be considerably faster, it really makes the UI inflexible to basic changes (else you face constantly changing the code). Additionally, white spaces and newlines are actually controls. So in the above code, you''''d get:
   1:  e.Item.Controls[0] //"\r\n            1 - \r\n            "
   2:  e.Item.Controls[1] //is the actual "see" literal
Which is both an unexpected behaviour and one very hard to cleanly deal with.

When it comes to OnItemDataBound, the sky is the limit. Here we''''ve only shown a basic example of what can be done and though we will see other, more complex examples, we won''''t cover every possibility.

OnItemCreated

Another useful event exposed by these controls is OnItemCreated. The key difference between the two is that OnItemDataBound only fires when the control is bound - that is when you are posting back and the control is recreated from the viewstate, OnItemDataBound doesn''''t fire. OnItemCreated on the other hand fires when a control is bound AS WELL AS when the control is recreated from the viewstate. The following example shows this subtle difference:
   1:  <asp:Repeater OnItemCreated="repeater_ItemCreated" OnItemDataBound="repeater_ItemDataBound" id="repeater" Runat="server">  
   2:   <ItemTemplate>
   3:    <asp:Literal EnableViewState="False" ID="event" Runat="server" /> <br />
   4:   </ItemTemplate>        
   5:  </asp:Repeater>
   6:   
   7:  <asp:Button ID="btn" Runat="server" Text="Click Me!" />
Here we have a repeater with both the OnItemCreated and OnItemDataBound events hooked [1]. Additionaly we have a single literal who''''s viewstate is disabled (if it was enabled we couldn''''t see the difference) [3]. And we have a button that''''ll do nothing but postback [7]. Our codebehind looks like:
   1:  private void Page_Load(object sender, EventArgs e) {
   2:   if (!Page.IsPostBack){
   3:    repeater.DataSource = CustomerUtility.GetAllOrders();
   4:    repeater.DataBind();
   5:   }
   6:  }
   7:  protected void repeater_ItemDataBound(object source, RepeaterItemEventArgs e) {
   8:   if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item){
   9:    Literal lit = (Literal)e.Item.FindControl("event");
  10:    if (lit != null){
  11:     lit.Text += " - ItemDataBound";
  12:    }
  13:   }
  14:  }
  15:  protected void repeater_ItemCreated(object source, RepeaterItemEventArgs e) {
  16:   if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item){
  17:    Literal lit = (Literal)e.Item.FindControl("event");
  18:    if (lit != null){
  19:     lit.Text += "ItemCreated";
  20:    }
  21:   }
  22:  }
When the page is first loaded, Page.IsPostBack returns false [2] and our repeater is bound to all orders [3,4]. Calling DataBind() causes the ItemCreated event to fire for the first row, followed by the ItemDataBound event - in our example each will fire, one after the other, 11 times (since there are 11 orders). As we can see, ItemCreated and ItemDataBound merely take the literal and append the text "ItemCreated" and "ItemDataBound" respectively. The difference happens when our button is clicked. This causes Page_Load to fire, but this time Page.IsPostBack evaluates to true, thus skipping the binding [3,4]. Only when the page enters its Begin PreRender stage will the ItemCreated event fire (again once for each row), but this time it won''''t be followed by the ItemDataBound.

The really important thing to keep in mind is that when ItemCreated fires because of databinding, e.Item.DataItem will what you expect - a reference to the individual row being bound. However, when ItemCreated is fired from being re-created from the viewstate, e.Item.DataItem will be NULL. If you think about it this makes sense, the entire datasource isn''''t stored in the viewstate, only the individual controls and their values, as such its impossible to have access to the individual rows of data originally used when binding. Of course, this can lead to very buggy code. For example, if we took our previous ItemDataBound example and moved it to the ItemCreated event:
   1:  protected void itemCreatedRepeater_ItemCreatedobject source, RepeaterItemEventArgs e) {
   2:   if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item){
   3:    Literal lit = (Literal)e.Item.FindControl("see");
   4:    if (lit != null){
   5:     Owner owner = (Owner)e.Item.DataItem;
   6:     if (owner.Pets.Count == 0){
   7:      lit.Text = "no pets";
   8:     }else{
   9:      lit.Text = "see pets";
  10:     }
  11:    }
  12:   }
  13:  }
When the page first loads, the above code will work fine. But if the page is postedback, e.Item.DataItem will be null, resulting in a runtime null reference error.

Nested Binding

Another common requirement is to nest controls within each other. Both of our sample data has a 1 to many relationship and are therefore ideal candidates. Our Customers dataset has a DataRelation set up between the Customer''''s customerId and the order''''s customerId:
   1:  ds.Relations.Add(new DataRelation("CustomerOrders", ds.Tables[0].Columns["CustomerId"], ds.Tables[1].Columns["CustomerId"]));
And our Owner''''s have a Pets property which is a collection of all the pets they own.

The two ways that we''''ll look at nesting repeaters is via inline binding and using OnItemDataBound.

Inline

   1:  <asp:Repeater id="dataSetCasting" Runat="server">
   2:   <HeaderTemplate>
   3:    <ul>
   4:   </HeaderTemplate>
   5:   <ItemTemplate>
   6:    <li><%# ((DataRowView)Container.DataItem)["Name"]%>
   7:     <ul>
   8:     <asp:Repeater ID="orders" DataSource=''''<%# ((DataRowView)Container.DataItem).CreateChildView("CustomerOrders")%>'''' Runat="server">
   9:      <ItemTemplate>
  10:       <li><%# ((DataRowView)Container.DataItem)["Amount"]%></li>
  11:      </ItemTemplate>
  12:     </asp:Repeater>
  13:     </ul>
  14:    </li>
  15:   </ItemTemplate>
  16:   <FooterTemplate>
  17:    </ul>
  18:   </FooterTemplate>
  19:  </asp:Repeater>
The important part being when we set the DataSource of our inner repeater [8]. The CreateChildView function our DataRowView is used, in conjuction with the name of our DataRelationship to return a DataView of all child records. Alternatively, using the DataBinder.Eval, we could simply use:
   1:  <asp:Repeater ID="orders" DataSource=''''<%# DataBinder.Eval(Container.DataItem, "CutomerOrders")%>'''' Runat="server">
Again, we use the CustomerOrders datarelation which we created, but let the DataBinder.Eval handle everything else.

Nesting with custom collections is even easier. Since owners have a property called Pets which is a custom collection of all the pets they own, we can simply:
   1:  <asp:Repeater id="collectionCasting" Runat="server">
   2:   <HeaderTemplate>
   3:    <ul>
   4:   </HeaderTemplate>
   5:   <ItemTemplate>
   6:    <li><%# ((Owner)Container.DataItem).FirstName%> 
   7:     <ul>
   8:     <asp:Repeater ID="pets" DataSource="<%# ((Owner)Container.DataItem).Pets%>" Runat="server">
   9:      <ItemTemplate>
  10:       <li><%# ((Pet)Container.DataItem).Name%></li>
  11:      </ItemTemplate>
  12:     </asp:Repeater>
  13:     </ul>
  14:    </li>
  15:   </ItemTemplate>
  16:   <FooterTemplate>
  17:    </ul>
  18:   </FooterTemplate>
  19:  </asp:Repeater>
Or using DataBinder.Eval:
   1:  <asp:Repeater ID="pets" DataSource=''''<%# DataBinder.Eval(Container.DataItem, "Pets")%>'''' Runat="server">

OnItemDataBound

If something is doable using inline ASPX, it''''s doable via onItemDataBound. Deciding which method to use often depends on which you feel is cleaner and more flexible. We''''ll only look at one example, since it''''s basically the same as the above code, except the binding logic is moved to codebehind:
   1:  <asp:Repeater OnI

上一页  [1] [2] [3]  下一页


[Web开发]一个关于ASP运行时间计算的代码  [Web开发]ASP:检测含有中文字符串的实际长度
[Web开发]asp 中英文字符长度检测判断函数  [Web开发]安全维护 IIS asp 站点的高级技巧
[Access]ASP&SQL让select查询结果随机排序的实现方法  [Web开发]ASP字符串截取函数
[Web开发][asp]关键词只替换一次的写法  [Web开发]Asp无组件生成缩略图方法详解
[Web开发]asp编程中优化数据库方法详解  [Web开发]三种方法教你asp如何去除html标记
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Web开发  · 网页制作
    · 平面设计  · 网站运营
    · 网站推广  · 搜索优化
    · 建站心得  · 站长故事
    · 互联动态
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台