自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一句代碼實(shí)現(xiàn)批量數(shù)據(jù)綁定 上

數(shù)據(jù)庫
對(duì)于一個(gè)以數(shù)據(jù)處理為主的應(yīng)用中的UI層,我們往往需要編寫相當(dāng)多的代碼去實(shí)現(xiàn)數(shù)據(jù)綁定。本篇著重介紹如何通過這個(gè)組件來解決我們?cè)谶M(jìn)行數(shù)據(jù)綁定過程中的常見問題,下篇會(huì)介紹它的設(shè)計(jì)。

對(duì)于一個(gè)以數(shù)據(jù)處理為主的應(yīng)用中的UI層,我們往往需要編寫相當(dāng)多的代碼去實(shí)現(xiàn)數(shù)據(jù)綁定。如果界面上的控件和作為數(shù)據(jù)源的實(shí)體類型之間存儲(chǔ)某種約定的映射關(guān)系,我們就可以實(shí)現(xiàn)批量的數(shù)據(jù)綁定。為了驗(yàn)證這種想法,我寫了一個(gè)小小的組件。這個(gè)小玩意僅僅是我花了兩個(gè)小時(shí)寫的,其中還有很多問題沒有解決,比如對(duì)于空值的處理,特殊控件屬性值的HTML編碼問題,以及頻繁反射的性能問題,僅僅演示一種解決思路而已。本篇著重介紹如何通過這個(gè)組件來解決我們?cè)谶M(jìn)行數(shù)據(jù)綁定過程中的常見問題,下篇會(huì)介紹它的設(shè)計(jì)。

目錄:

  1. 基于控件ID/實(shí)體屬性名映射的數(shù)據(jù)綁定
  2. 一句代碼實(shí)現(xiàn)批量數(shù)據(jù)綁定
  3. 修正綁定數(shù)據(jù)的顯示格式
  4. 過濾不需要綁定的屬性
  5. 多個(gè)控件對(duì)應(yīng)同一個(gè)實(shí)體屬性

#p#

一、基于控件ID/實(shí)體屬性名映射的數(shù)據(jù)綁定

我的這個(gè)組件暫時(shí)命名為DataBinder好了(注意和System.Web.UI.DataBinder區(qū)分),我們用它來將一個(gè)實(shí)體對(duì)象綁定給指定的容器控件中的所有子控件。下面是DataBinder的定義,兩個(gè)BindData方法實(shí)現(xiàn)具體的綁定操作。

  1. public class DataBinder     
  2.      
  3.     public event EventHandler<DataBindingEventArgs> DataItemBinding;     
  4.     public event EventHandler<DataBindingEventArgs> DataItemBound;     
  5.       
  6.     public static IEnumerable<BindingMapping> BuildBindingMappings(Type entityType, Control container, string suffix = "");             
  7.     public void BindData(object entity, Control container, string suffix = "");     
  8.     public void BindData( object entity,IEnumerable<BindingMapping> bindingMappings);    

本文開頭所說,自動(dòng)批量的數(shù)據(jù)綁定依賴于控件和作為數(shù)據(jù)源實(shí)體類型的映射關(guān)系。在這里,我直接采用控件ID和實(shí)體屬性名之間的映射。也就是說,在對(duì)于界面上控件進(jìn)行命名的時(shí)候,應(yīng)該根據(jù)對(duì)應(yīng)的實(shí)體類型屬性名進(jìn)行規(guī)范命名。

另一方面,作為數(shù)據(jù)源的對(duì)象來說,它的所有屬性并不都是為數(shù)據(jù)綁定而涉及。為了讓DataBinder能夠自動(dòng)篩選用于綁定的屬性,我在相應(yīng)的屬性上應(yīng)用了一個(gè)自定義特性:DataPropertyAttribute。比如,下面的Customer對(duì)象會(huì)在后續(xù)的演示中用到,它的每一個(gè)數(shù)據(jù)屬性都應(yīng)用了這樣一個(gè)DataPropertyAttribute特性。

  1. public class Customer     
  2. {     
  3.     [DataProperty]     
  4.     public string ID { get; set; }     
  5.     [DataProperty]     
  6.     public string FirstName { get; set; }     
  7.     [DataProperty]     
  8.     public string LastName { get; set; }     
  9.     [DataProperty]    
  10.     public string Gender { get; set; }    
  11.     [DataProperty]    
  12.     public int? Age { get; set; }    
  13.     [DataProperty]    
  14.     public DateTime? BirthDay { get; set; }    
  15.     [DataProperty]    
  16.     public bool? IsVip { get; set; }    

#p#

二、一句代碼實(shí)現(xiàn)批量數(shù)據(jù)綁定

現(xiàn)在我們就來演示如何通過我們定義的DataBinder實(shí)現(xiàn)“一句代碼的數(shù)據(jù)批量綁定”,而作為數(shù)據(jù)源就是我們上面定義的Customer對(duì)象。我們先來設(shè)計(jì)我們的頁面,下面是主體部分的HTML,這是一個(gè)表格。需要注意的是:所有需要綁定到Customer對(duì)象的空間都和對(duì)應(yīng)的屬性具有相同的ID。

  1. <table>     
  2.  <tr>     
  3.      <td style="width:20%;text-align:right">ID:</td>     
  4.      <td><asp:Label ID="ID" runat="server"></asp:Label></td>     
  5.  </tr>     
  6.   <tr>     
  7.      <td style="width:20%;text-align:right">First Name:</td>     
  8.      <td><asp:TextBox ID="FirstName" runat="server"></asp:TextBox></td>     
  9.  </tr>    
  10.   <tr>    
  11.      <td style="width:20%;text-align:right">Last Name:</td>    
  12.      <td><asp:TextBox ID="LastName" runat="server"></asp:TextBox></td>    
  13.  </tr>    
  14.   <tr>    
  15.      <td style="width:20%;text-align:right">Gender:</td>    
  16.      <td>    
  17.          <asp:RadioButtonList ID="Gender" runat="server" RepeatDirection="Horizontal">    
  18.              <asp:ListItem Text="Male"   Value = "Male" />    
  19.              <asp:ListItem Text="Female" Value = "Female" />    
  20.          </asp:RadioButtonList>    
  21.      </td>    
  22.  </tr>    
  23.   <tr>    
  24.      <td style="width:20%;text-align:right">Age:</td>    
  25.      <td><asp:TextBox ID="Age" runat="server"></asp:TextBox></td>    
  26.  </tr>    
  27.   <tr>    
  28.      <td style="width:20%;text-align:right">Birthday:</td>    
  29.      <td><asp:TextBox ID="Birthday" runat="server" Width="313px"></asp:TextBox></td>    
  30.  </tr>    
  31.   <tr>    
  32.      <td style="width:20%;text-align:right">Is VIP:</td>    
  33.      <td><asp:CheckBox ID="IsVip" runat="server"></asp:CheckBox></td>    
  34.  </tr>    
  35.   <tr>     
  36.      <td colspan="2" align="center">    
  37.          <asp:Button ID="ButtonBind" runat="server" Text="Bind" onclick="ButtonBind_Click" />    
  38.      </td>    
  39.  </tr>    
  40. /table> 

為了編成方便,將DataBinder對(duì)象作為Page類型的一個(gè)屬性,該屬性在構(gòu)造函數(shù)中初始化。

  1. public partial class Default : System.Web.UI.Page  
  2. {  
  3.     public Artech.DataBinding.DataBinder DataBinder { get; private set; }  
  4.     public Default()  
  5.     {  
  6.         this.DataBinder = new Artech.DataBinding.DataBinder();  
  7.     }  

然后我將數(shù)據(jù)綁定操作實(shí)現(xiàn)的Bind按照的Click事件中,對(duì)應(yīng)所有的代碼如下所示——真正的用于數(shù)據(jù)綁定的代碼只有一句。

  1. protected void ButtonBind_Click(object sender, EventArgs e)  
  2. {  
  3.     var customer = new Customer  
  4.     {  
  5.         ID          = Guid.NewGuid().ToString(),  
  6.         FirstName   = "Zhang",  
  7.         LastName    = "San",  
  8.         Age         = 30,  
  9.         Gender      = "Male",  
  10.        BirthDay    = new DateTime(1981, 1, 1),  
  11.        IsVip       = true 
  12.    };  
  13.    this.DataBinder.BindData(customer, this);  

在瀏覽器中打開該Web頁面,點(diǎn)擊Bind按鈕,你會(huì)發(fā)現(xiàn)綁定的數(shù)據(jù)已經(jīng)正確顯示在了對(duì)應(yīng)的控件中:

 

#p#

三、修正綁定數(shù)據(jù)的顯示格式

雖然通過DataBinder實(shí)現(xiàn)了對(duì)多個(gè)控件的批量綁定,但是并不***。一個(gè)顯著的問題是:作為生日的字段不僅僅顯示了日期,還顯示了時(shí)間。我們?nèi)绾巫屓掌诎凑瘴覀円蟮母袷竭M(jìn)行顯示呢?DataBinder為了提供了三種選擇。

如果你注意看DataBinder定義了,你會(huì)發(fā)現(xiàn)它定義了兩個(gè)事件:DataItemBinding和DataItemBound(命名有待商榷),它們分別在對(duì)某個(gè)控件進(jìn)行綁定之前和之后觸發(fā)。我們的***種方案就是注冊(cè)DataItemBinding時(shí)間,為Birthday指定一個(gè)格式化字符串。假設(shè)我們需要的格式是“月-日-年”,那么我們指定的格式化字符串:MM-dd-yyyy。事件注冊(cè)我方在了Page的構(gòu)造函數(shù)中:

  1.  public Default()  
  2.  {  
  3.      this.DataBinder = new Artech.DataBinding.DataBinder();  
  4.      this.DataBinder.DataItemBinding += (sender, args) => 
  5.          {  
  6.              if (args.BindingMapping.Control == this.Birthday)  
  7.              {  
  8.                  args.BindingMapping.FormatString = "MM-dd-yyyy";  
  9.              }  
  10.         };  

運(yùn)行程序,你會(huì)發(fā)現(xiàn)作為生日的字段已經(jīng)按照我們希望的格式顯示出來:

 

上面介紹了通過注冊(cè)DataItemBinding事件在綁定前指定格式化字符串的解決方案,你也可以通過注冊(cè)DataItemBound事件在綁定后修正顯示的日期格式,相應(yīng)的代碼如下:

  1. public Default()  
  2. {  
  3.     this.DataBinder = new Artech.DataBinding.DataBinder();  
  4.     this.DataBinder.DataItemBound += (sender, args) => 
  5.         {  
  6.             if (args.BindingMapping.Control == this.Birthday && null != args.DataValue)  
  7.             {  
  8.                 this.Birthday.Text = ((DateTime)Convert.ChangeType(args.DataValue, typeof(DateTime))).  
  9.                     ToString("MM-dd-yyyy");  
  10.            }  
  11.        };  

DataBinder定義了兩個(gè)BindData重載,我們使用的是通過指定數(shù)據(jù)源和容器控件的方式,而另一個(gè)重載的參數(shù)為IEnumerable<BindingMapping>類型。而BindingMapping是我們自定義的類型,用于表示控件和實(shí)體屬性之間的運(yùn)行時(shí)映射關(guān)系。而這樣一個(gè)BindingMapping集合,可以通過DataBinder的靜態(tài)方法BuildBindingMappings來創(chuàng)建。BindingMapping具有一個(gè)FormatString表示格式化字符串(實(shí)際上面我們指定的格式化字符串就是為這個(gè)屬性指定的)。那么,我們也可以通過下面的代碼來進(jìn)行數(shù)據(jù)綁定:

  1. protected void ButtonBind_Click(object sender, EventArgs e)  
  2. {  
  3.     var customer = new Customer  
  4.     {  
  5.         ID          = Guid.NewGuid().ToString(),  
  6.         FirstName   = "Zhang",  
  7.         LastName    = "San",  
  8.         Age         = 30,  
  9.         Gender      = "Male",  
  10.        BirthDay    = new DateTime(1981, 1, 1),  
  11.        IsVip       = true 
  12.    };  
  13.    var bindingMappings = Artech.DataBinding.DataBinder.BuildBindingMappings(typeof(Customer), this);  
  14.    bindingMappings.Where(mapping => mapping.Control == this.Birthday).First().FormatString = "MM-dd-yyyy";  
  15.    this.DataBinder.BindData(customer, bindingMappings);  

#p#

四、過濾不需要綁定的屬性

在默認(rèn)的情況下,***個(gè)BindData方法(指定容器控件)會(huì)遍歷實(shí)體的所有屬性,將其綁定到對(duì)應(yīng)的控件上??赡茉谟械臅r(shí)候,對(duì)于某些特殊的屬性,我們不需要進(jìn)行綁定。比如,某個(gè)控件的ID雖然符合實(shí)體屬性的映射,但是它們表示的其實(shí)根本不是相同性質(zhì)的數(shù)據(jù)。

為了解決在這個(gè)問題,在BindingMapping類型中定義了一個(gè)布爾類型的AutomaticBind屬性。如果你在綁定前將該屬性設(shè)置成False,那么基于該BindingMapping的數(shù)據(jù)綁定將被忽略。如果你調(diào)用BindData(object entity, Control container, string suffix = "")這個(gè)重載,你可以通過注冊(cè)DataItemBinding事件將相應(yīng)BindingMapping的AutomaticBind屬性設(shè)置成False。如果你調(diào)用BindData( object entity,IEnumerable<BindingMapping> bindingMappings)這個(gè)重載,你只需要在調(diào)用之間將相應(yīng)BindingMapping的AutomaticBind屬性設(shè)置成False。

我們將我們的程序還原成最初的狀態(tài),現(xiàn)在通過注冊(cè)BindingMapping事件將基于Birthday的BindingMapping的AutomaticBind屬性設(shè)置成False:

  1.  public Default()  
  2.  {  
  3.      this.DataBinder = new Artech.DataBinding.DataBinder();  
  4.      this.DataBinder.DataItemBinding += (sender, args) => 
  5.          {  
  6.              if (args.BindingMapping.Control == this.Birthday)  
  7.              {  
  8.                  args.BindingMapping.AutomaticBind = false;  
  9.              }  
  10.         };  

程序執(zhí)行后,Birthday對(duì)應(yīng)的TextBox將不會(huì)被綁定:

 

#p#

五、多個(gè)控件對(duì)應(yīng)同一個(gè)實(shí)體屬性

在上面的例子中,我們的控件的ID和對(duì)應(yīng)的實(shí)體屬性是相同的。但是在很多情況下,相同的頁面上有不止一個(gè)控件映射到實(shí)體的同一個(gè)屬性上。而控件ID的唯一性決定了我們不能為它們起相同的ID。在這種情況下,我們采用“基于后綴”的映射。也就是為,在為控件進(jìn)行命名的時(shí)候,通過“實(shí)體屬性名+后綴”形式來指定。

如果你仔細(xì)看了DataBinder的定義,不論是實(shí)例方法BindData(接受Control類型參數(shù)的),還是靜態(tài)方法BuildBindingMappings,都具有一個(gè)缺省參數(shù)suffix,這就是為這種情況設(shè)計(jì)的。在默認(rèn)的情況下,這個(gè)參數(shù)的值為空字符串,所以我們需要控件和實(shí)體屬性具有相同的名稱。如果控件是基于“實(shí)體屬性名+后綴”來命名的,就需要顯式指定這個(gè)參數(shù)了。為了演示這種情況,我們將例子中的所有需要綁定的空間ID加上一個(gè)“_Xyz”字符作為后綴。

  1. <table> 
  2.  <tr> 
  3.      <td style="width:20%;text-align:right">ID:</td> 
  4.      <td><asp:Label ID="ID_Xyz" runat="server"></asp:Label></td> 
  5.  </tr> 
  6.   <tr> 
  7.      <td style="width:20%;text-align:right">First Name:</td> 
  8.      <td><asp:TextBox ID="FirstName_Xyz" runat="server"></asp:TextBox></td> 
  9.  </tr> 
  10.  <tr> 
  11.     <td style="width:20%;text-align:right">Last Name:</td> 
  12.     <td><asp:TextBox ID="LastName_Xyz" runat="server"></asp:TextBox></td> 
  13. </tr> 
  14.  <tr> 
  15.     <td style="width:20%;text-align:right">Gender:</td> 
  16.     <td> 
  17.         <asp:RadioButtonList ID="Gender_Xyz" runat="server" RepeatDirection="Horizontal"> 
  18.             <asp:ListItem Text="Male"   Value = "Male" /> 
  19.             <asp:ListItem Text="Female" Value = "Female" /> 
  20.         </asp:RadioButtonList> 
  21.     </td> 
  22. </tr> 
  23. <tr> 
  24.     <td style="width:20%;text-align:right">Age:</td> 
  25.     <td><asp:TextBox ID="Age_Xyz" runat="server"></asp:TextBox></td> 
  26. </tr> 
  27.  <tr> 
  28.     <td style="width:20%;text-align:right">Birthday:</td> 
  29.     <td><asp:TextBox ID="Birthday_Xyz" runat="server" Width="313px"></asp:TextBox></td> 
  30. </tr> 
  31.  <tr> 
  32.     <td style="width:20%;text-align:right">Is VIP:</td> 
  33.     <td><asp:CheckBox ID="IsVip_Xyz" runat="server"></asp:CheckBox></td> 
  34. </tr> 
  35.  <tr> 
  36.     <td colspan="2" align="center"> 
  37.         <asp:Button ID="ButtonBind" runat="server" Text="Bind" onclick="ButtonBind_Click" /> 
  38.     </td> 
  39. </tr> 
  40. /table> 

如果采用指定容器控件進(jìn)行直接綁定的話,就可以這樣編程:

  1. protected void ButtonBind_Click(object sender, EventArgs e)  
  2. {  
  3.     var customer = new Customer  
  4.     {  
  5.         ID          = Guid.NewGuid().ToString(),  
  6.         FirstName   = "Zhang",  
  7.         LastName    = "San",  
  8.         Age         = 30,  
  9.         Gender      = "Male",  
  10.        BirthDay    = new DateTime(1981, 1, 1),  
  11.        IsVip       = true 
  12.    };  
  13.    this.DataBinder.BindData(customer, this, "_Xyz");  

如果通過預(yù)先創(chuàng)建的BindingMapping集合進(jìn)行數(shù)據(jù)綁定,那么代碼將是這樣:

  1.  protected void ButtonBind_Click(object sender, EventArgs e)  
  2.  {  
  3.      var customer = new Customer  
  4.      {  
  5.          ID          = Guid.NewGuid().ToString(),  
  6.          FirstName   = "Zhang",  
  7.          LastName    = "San",  
  8.          Age         = 30,  
  9.          Gender      = "Male",  
  10.         BirthDay    = new DateTime(1981, 1, 1),  
  11.         IsVip       = true 
  12.     };  
  13.     
  14.     var bindingMappings = Artech.DataBinding.DataBinder.BuildBindingMappings(typeof(Customer), this, "_Xyz");  
  15.     this.DataBinder.BindData(customer, bindingMappings);  

 原文鏈接:http://www.cnblogs.com/artech/archive/2011/03/23/databinding.html

【編輯推薦】

  1. DBA應(yīng)用技巧:如何升級(jí)InnoDB Plugin
  2. 十個(gè)節(jié)省時(shí)間的MySQL命令
  3. DBA必備:MySQL數(shù)據(jù)庫常用操作和技巧
  4. MySQL日志操作教程:DBA們管理的利器
  5. MySQL觸發(fā)器如何正確使用

 

責(zé)任編輯:艾婧 來源: 博客園
相關(guān)推薦

2011-03-28 15:48:52

批量數(shù)據(jù)綁定

2012-02-09 09:41:22

2023-11-06 08:31:58

業(yè)務(wù)代碼多線程

2021-05-11 15:34:04

Task.Result代碼Winform

2011-06-13 09:25:01

斷號(hào)

2013-03-22 10:53:42

PyConPython

2009-03-10 18:10:12

LinuxUbuntu技巧

2023-07-12 08:01:28

FOADMROADMOXC

2021-12-17 08:55:26

Python微博機(jī)器人

2019-11-15 18:00:18

MySQLSQL數(shù)據(jù)庫

2013-05-10 10:56:09

2023-09-05 23:34:52

Kubernetes云原生

2009-10-29 09:57:16

VB.NET實(shí)現(xiàn)數(shù)據(jù)綁

2015-08-03 10:21:04

設(shè)計(jì)模式表達(dá)

2020-11-27 09:57:11

Python代碼PyPy

2022-08-01 10:01:11

JavaScript語言代碼庫

2014-12-16 08:58:17

甲骨文Oracle數(shù)據(jù)庫選件

2025-03-13 11:09:47

2016-09-12 15:26:06

戴爾

2023-08-25 17:10:14

LLM人工智能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)