程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> ASP.NET基礎 >> 在ASP.NET 2.0中操作數據之十二:在GridView控件中使用TemplateField

在ASP.NET 2.0中操作數據之十二:在GridView控件中使用TemplateField

編輯:ASP.NET基礎

導言

  GridView是由一組字段(Field)組成的,它們都指定的了來自DataSource中的什麼屬性需要用到自己的輸出呈現中。最簡單的字段類型是BoundField,它僅將數據簡單的顯示為文本。其他的字段類型使用交互HTML元素(alternate HTML elements)來顯示數據。比如說,CheckBoxField將被呈現為一個CheckBox,其選中狀態由某特定數據字段的值來決定;ImageField則將某特定數據字段呈現為一個圖片,當然,這個數據字段中應該放的是圖片類型的數據。超級鏈接和按鈕的狀態取決於使用HyperLinkField或ButtonField字段類型的數據字段的值。

  雖然CheckBoxField、ImageField、HyperLinkField和ButtonField考慮到了數據的交互視圖,但它們仍然有一些相關的格式化的限制。CheckBoxField只可以顯示為一個單個的CheckBox,而一個ImageField則只可以顯示為一張圖片。如果某個字段要顯示一些文本、復選框、圖片還有一些其他基於不同數據的東西的時候,我們要做什麼?或者說,如果我們需要使用除了CheckBox、Image、HyperLink以及Button之外的Web控件來顯示數據時,我們該怎麼辦?此外,BoundField只能顯示一個單獨的數據字段。如果我們想要在一個GridView列中顯示兩個或者更多的數據字段的值的時候該怎麼辦呢?

  為了適應這樣的一個復雜的情況,GridView提供了使用模板來進行呈現的TemplateField。模板可以包括靜態的HTML、Web控件以及數據綁定的代碼。此外,TemplateField還擁有各種可以用於不同情況的頁面呈現的模板。比如說,ItemTemplate是默認的用於呈現每行中的單元格的,而EditItemTemplate則用於編輯數據時的自定義界面。

  在本節教程中,我們將解釋如何使用TemplateField來更加高級的自定義GridView控件。在上一節教程中,我們看到了如何使用DataBound和RowDataBound事件處理方法來自定義基於數據的格式化。另一個辦法就是在模板中調用一個格式化方法。在本節中,我們就會看到這種技術。

  在本節中,我們將使用一些TemplateField來自定義雇員信息的呈現。特別的,我們將列出所有的雇員,但我們將會把雇員的姓和名字放在一列中,把他們的雇傭日期放在一個Calendar控件中,還將用一個狀態列來表明他們來到公司有多久了。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524049.png

圖一:使用三個TemplateField來自定義信息的顯示方式

第一步:將數據綁定到GridView

  當你需要使用一些TemplateField來自定義顯示時,我發現最簡單的就是先創建一個僅包含BoundField的GridView控件,然後添加一些TemplateField,如果需要的話,也可以將某些BoundField直接轉換成TemplateField。好了,讓我們開始本節教程吧。首先,通過設計器往頁面上添加一個GridView控件,並將一個返回雇員信息的ObjectDataSource綁定到它上面。這些步驟將創建一個帶有一些BoundField的GridView,這些BoundField對應雇員信息中不同的字段。

  打開GridViewTemplateField.aspx,並從工具箱中拖一個GridView到設計器上。從GridView的智能標簽(smart tag)上選擇並添加一個新的調用EmployeesBLL 類的GetEmployees()方法的ObjectDataSource控件。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524050.png

圖二:添加一個新的調用GetEmployees()方法的ObjectDataSource控件

  用這種方式綁定GridView將會自動的為雇員信息的每一個屬性添加一個BoundField:EmployeeID、LastName、FirstName、Title、HireDate、ReportsTo以及Country。在這個報表中,我們不希望看到EmployeeID、ReportsTo以及Country屬性。要刪除這些BoundField的話,你可以:

·使用字段對話框 - 在GridView的智能標簽的彈出菜單中點擊“編輯列”(Edit Columns)。然後,在左下角的列表中選中你想要刪除的BoundField並點擊那個帶紅叉的按鈕,就可以刪除這個BoundField了。

·手工編輯GridView的聲明語句 - 在源視圖(Source view)中,找到你想要刪除的BoundField,就是那些<asp:BoundField>元素,刪了就行了。

在你刪了EmployeeID、ReportsTo和Country等BoundField之後,你的GridView的標記語言代碼應該像這個樣子:

<asp:GridView ID="GridView1" runat="server"
 AutoGenerateColumns="False" DataKeyNames="EmployeeID"
 DataSourceID="ObjectDataSource1">
 <Columns>
 <asp:BoundField DataField="LastName" HeaderText="LastName"
  SortExpression="LastName" />
 <asp:BoundField DataField="FirstName" HeaderText="FirstName"
  SortExpression="FirstName" />
 <asp:BoundField DataField="Title" HeaderText="Title"
  SortExpression="Title" />
 <asp:BoundField DataField="HireDate" HeaderText="HireDate"
  SortExpression="HireDate" />
 </Columns>
</asp:GridView>

  讓我們花點時間在浏覽器中來看看我們的成果。這時,你將看到一個表格,表格中每一個記錄都是一個雇員的信息,一共有四列:一個是雇員的姓,一個是名字,一個是頭銜,還有一個是他們的受雇日期。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524065.png

圖三:每一個雇員信息都顯示了LastName、FirstName、Title和HireDate

第二步:將姓和名顯示在一列中

  現在,每一個雇員的姓和名都是分開在兩列中顯示的。把它們放到一個列中顯示出來也許是一個不錯的主意。要做到這一點,我們需要用到TemplateField。我們可以添加一個新的TemplateField,給它加上一些必須的標記語言和數據綁定代碼,然後刪除原來的FirstName和 LastName這兩個BoundField;當然,我們也可以將FirstName這個BoundField直接轉換成一個TemplateField,編輯它以加上LastName的值,然後再刪除LastName這個BoundField。

  兩種辦法都行,不過我個人還是比較喜歡直接轉換的那種,因為這種方式可以自動的添加一個含有Web控件和相應的數據綁定代碼的ItemTemplate和EditItemTemplate,它們可以用來模仿一個BoundField的呈現和功能。這樣做的好處自然是不言而喻的,因為轉換的過程已經幫我們做了很多事情,那我們當然就可以節約不少的時間了。

  要將一個BoundField轉換成TemplateField,我們可以在GridView的智能標簽的彈出菜單中點擊“編輯列”(Edit Columns)。在彈出對話框的左下角的列表中選擇需要轉換的BoundField,然後點擊右下角的“將此列轉換成模板列”(Convert this field into a TemplateField)即可。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524152.png

圖四:在字段對話框中,將一個綁定列轉換成一個模板列

  讓我們繼續將FirstName這個BoundField轉換成TemplateField。在這個更改之後,設計器中並沒有什麼明顯的不同。這是因為將BoundField轉換成TemplateField時,其實是創建了一個維持之前的BoundField的外觀和感覺的TemplateField。盡管在設計器中沒有視覺上的變化,但是這個轉換的過程已經將BoundField的聲明代碼——<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />——改成了如下所示的TemplateField的聲明代碼:

<asp:TemplateField HeaderText="FirstName" SortExpression="FirstName">
 <EditItemTemplate>
 <asp:TextBox ID="TextBox1" runat="server"
  Text='<%# Bind("FirstName") %>'></asp:TextBox>
 </EditItemTemplate>
 <ItemTemplate>
 <asp:Label ID="Label1" runat="server"
  Text='<%# Bind("FirstName") %>'></asp:Label>
 </ItemTemplate>
</asp:TemplateField>

  就像你看到的那樣,TemplateField由兩個模板組成——一個ItemTemplate,它有一個Label控件,其Text屬性被設置為FirstName數據字段的值;還有一個EditItemTemplate,它有一個TextBix控件,其Text屬性也被設置為FirstName數據字段的值。數據綁定語法——<%# Bind("fieldName") %>——說明數據字段fieldName 被綁定到了這個特定的Web控件的屬性上。

  要將LastName添加到TemplateField中,我們需要為ItemTemplate添加一個Label控件並將其Text屬性綁定到LastName上。通過設計器或是手工編寫代碼都可以做到這一點。要手工寫代碼的話,只需簡單的將相應的聲明代碼添加到ItemTemplate中即可,如下所示:

<asp:TemplateField HeaderText="FirstName" SortExpression="FirstName">
 <EditItemTemplate>
 <asp:TextBox ID="TextBox1" runat="server"
  Text='<%# Bind("FirstName") %>'></asp:TextBox>
 </EditItemTemplate>
 <ItemTemplate>
 <asp:Label ID="Label1" runat="server"
  Text='<%# Bind("FirstName") %>'></asp:Label>
 <asp:Label ID="Label2" runat="server"
  Text='<%# Bind("LastName") %>'></asp:Label>
 </ItemTemplate>
</asp:TemplateField>

  要通過設計器來添加的話,還是在GridView的智能標簽的彈出菜單中點擊“編輯列”( Edit Templates)。這樣會顯示GridView的模板編輯界面。在這個界面中,智能標簽是GridView中模板的列表。因為這個時候我們只有一個TemplateField,所以下拉列表中只有FirstName的各種模板和EmptyDataTemplate以及PagerTemplate。

  如果指定了EmptyDataTemplate模板的話,它將用於綁定到GridView的數據源中沒有任何記錄時的輸出呈現;如果指定了PagerTemplate,它將用於呈現GridView的分頁界面。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524146.png

圖五:GridView的模板列可以通過設計器來編輯

  要在FirstName模板列中同時顯示LastName,從工具箱中拖一個Label到FirstName模板列的ItemTemplate中即可,當然,這要在GridView的模板編輯界面中才行的,如下圖所示:

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524125.png

圖六:向FirstName模板列的ItemTemplate中添加一個Label

  現在,添加到TemplateField的Label控件的Text屬性還是“Label”。我們需要修改這個以使這個屬性綁定到數據源中的LastName字段上。我們可以通過在Label控件的智能標記上點擊一下,然後在彈出菜單中選擇“編輯數據綁定”( Edit DataBindings)選項,如下圖所示:

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524153.png

圖七:從Label的智能標簽上選擇Edit DataBindings選項

  在彈出的數據綁定對話框中,你可以在左邊的列表中選擇需要綁定的屬性,然後在右邊的下來框中選擇一個數據字段。好了,我們現在在左邊選擇Text屬性,然後在右邊選擇LastName字段,點擊OK。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524221.png

圖八:將Text屬性綁定到LastName字段上

  注意:數據綁定對話框允許你聲明一個雙向的數據綁定。如果你保持“雙向數據綁定” (Two-way databinding)這個復選框為未選中的話,數據綁定的代碼將會是<%# Eval("LastName")%>而不是<%# Bind("LastName")%>。不過,對於本節教程來說,兩個種做法的效果都是OK的。雙向數據綁定在插入和編輯數據的時候將會比較重要。但是如果僅僅是簡單的顯示數據的話,兩種做法都是一樣的。我們將在今後的章節中詳細的討論一下雙向數據綁定。

  讓我們再花一些時間到浏覽器中看看這個頁面。就像你看到的那樣,GridView仍然包含4列,不過,FirstName列裡面顯示了姓和名兩個數據。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524276.png

圖九:姓和名顯示在同一列裡面了

  要完成這一步,我們先刪除LastName這個綁定列,並將FirstName這個模板列的列頭文本(HeaderText)改成“Name”。在這之後,GridView的聲明代碼將會像下面這樣:

<asp:GridView ID="GridView1" runat="server"
 AutoGenerateColumns="False" DataKeyNames="EmployeeID"
 DataSourceID="ObjectDataSource1">
 <Columns>
 <asp:TemplateField HeaderText="Name" SortExpression="FirstName">
  <EditItemTemplate>
  <asp:TextBox ID="TextBox1" runat="server"
   Text='<%# Bind("FirstName") %>'></asp:TextBox>
  </EditItemTemplate>
  <ItemTemplate>
  <asp:Label ID="Label1" runat="server"
   Text='<%# Bind("FirstName") %>'></asp:Label>
  <asp:Label ID="Label2" runat="server"
   Text='<%# Eval("LastName") %>'></asp:Label>
  </ItemTemplate>
 </asp:TemplateField>
 <asp:BoundField DataField="Title" HeaderText="Title"
  SortExpression="Title" />
 <asp:BoundField DataField="HireDate" HeaderText="HireDate"
  SortExpression="HireDate" />
 </Columns>
</asp:GridView>

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524266.png

圖十:每一個雇員的姓和名都顯示在同一列裡面了

第三步:使用Calendar控件顯示HiredDate字段

  在GridView中將數據顯示為文本的話,只需要簡單的使用BoundField就可以了。然而,在某些特定的場合,數據最好是展示為一個特殊的Web控件而不是一個簡單的文本。這樣的自定義的數據顯示就可以用TemplateField來做。比如說,比起將雇員的雇傭日期顯示成文本來說,我們覺得將其高亮的顯示在一個Calendar(使用Calendar控件)中會更爽一些。

  要做到這一點,先將HiredDate這個綁定列轉換成一個模板列。像之前做的那樣轉換就是了,大家應該還沒有忘記吧?在GridView的智能標簽那裡下手就可以了。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524291.png

圖十一:將HiredDate綁定列轉換成一個模板列

  就像我們在第二步中看到的那樣,這個操作會將綁定列替換成一個含有ItemTemplate和EditItemTemplate的模板列,其中的ItemTemplate和EditItemTemplate分別帶有一個Label和一個TextBox,而這個Label和TextBox的Text屬性都使用了數據綁定語句<%# Bind("HiredDate")%>來將HireDate綁定到自己身上。

  要用Calendar控件來替換這個文本的話,我們可以編輯模板:刪除Label控件,並添加上一個Calendar控件。在設計器中,從GridView的智能標簽的彈出菜單中選擇“編輯模板”(Edit Templates),並在下拉列表中選擇HireDate模板列的ItemTemplate。然後,刪除Label控件並從工具箱中拖一個Calendar控件到模板編輯界面中。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524282.png

圖十二:給HireDate模板列的ItemTemplate添加一個Calendar控件

  這個時候,GridView中每一行的HireDate模板列都會包含一個Calendar控件。不過,雇員的實際雇傭日期還沒有設置到Calendar控件上,這就讓Calendar控件默認的顯示為當前的日期。我們可以通過將雇員的HireDate賦值給Calendar控件的SelectedDate和VisibleDate屬性來修正這個問題。

從Calendar控件的智能標簽中選擇“編輯數據綁定”。然後,把SelectedDate和VisibleDate這兩個屬性都綁定到HireDate字段上。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524330.png

圖十三:將SelectedDate和VisibleDate都綁定到HireDate字段上

  注意:Calendar控件的選定日期不一定要可見。舉個例子來說,某個Calendar控件的選定日期為1999年4月1日,但卻顯示的是現在的年月。選定日期和可見日期是由Calendar控件的SelectedDate和VisibleDate屬性來指定的。因為我們不僅希望選中雇員的HireDate,還希望它是可見的,那麼我們就需要將這兩個屬性都綁定到HireDate字段上。

  現在,我們再到浏覽器中看看這個頁面,Calendar現在顯示的是雇員的雇員受雇日期的月份並選中了一個指定的日期。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524376.png

圖十四:雇員的受雇日期顯示到了Calendar控件上

  注意: 和我們一直所見到的那些例子相反,在本節教程中我們並沒有將GridView的EnableViewState屬性設置為false。這樣做的原因是,在Calendar控件上的點擊將會產生一個回發(PostBack),並將Calendar的選定日期設置為剛才所點擊的那個日期。如果禁用了GridView的ViewState,那麼每一次回發都將導致GridView使用原來的數據重新綁定,這樣Calendar的選定日期就會變成原來的雇員受雇日期。

  在本教程中,這是一個沒有意義的議題,因為用戶本來就不應該可以修改雇員的受雇日期。可能直接配置Calendar控件為不可選是最好的辦法。不過不管怎麼說,在本教程中可以看到,某些情況下還是將控件的ViewState啟用才能提供某些特定的功能的。

第四步:顯示雇員在公司工作了多少天

到現在,我們已經看到了TemplateField的兩個應用:

·將兩個數據合並到一個列中

·用一個Web控件來展示數據,而不是用一個簡單的文本

  第三種TemplateField的用法是,顯示GridView中數據的元數據。比如說,除了顯示雇員的受雇日期,我們可能還希望用一列來顯示這個雇員在公司干了多久。

  另外還有一種用法,它將在某些情況下需要用到,比如說在頁面上某個數據的顯示格式需要用一種不同於其在數據庫中的存儲格式的時候。想象一下,雇員表中有一個性別字段,其中存儲了M或是F這樣的字符用於表示此雇員是男的還是女的。當我們需要將這個信息顯示在頁面上的時候,我們可能希望能夠將其顯示為“男”或“女”而不是“M”或“F”。

  這兩種用法都可以采用在ASP.NET頁面的後置代碼類(或者是在一個獨立的類庫中,將其實現為一個靜態方法)創建一個供模板調用的格式化方法(formatting method)來做到。這樣的格式化方法將在模板中調用,語法跟前面的數據綁定語法是一樣的。格式化方法可以接受若干個參數,但是必須返回一個字符串。這個返回的字符串是一個用於插入到模板中的HTML。

  讓我們增加一點內容來說明這個概念。主要是增加一列以顯示雇員在公司干活的天數。這個格式化方法接受一個Northwind.EmployeesRow對象,然後返回以字符串的形式返回這個雇員在公司干活的天數。這個方法可以添加到ASP.NET頁面的後置代碼類中,不過一定要記得將其標記為protected或public,不然模板就訪問不到它了。

protected string DisplayDaysOnJob(Northwind.EmployeesRow employee)
{
 // Make sure HiredDate is not null... if so, return "Unknown"
 if (employee.IsHireDateNull())
 return "Unknown";
 else
 {
 // Returns the number of days between the current
 // date/time and HireDate
 TimeSpan ts = DateTime.Now.Subtract(employee.HireDate);
 return ts.Days.ToString("#,##0");
 }
}

  由於HiredDate可能會含有空值,所以我們必須在進行計算之前首先保證其值不為空。如果HiredDate值為空的話,直接返回一個“Unknown”就是了;如果不為空的話呢,就計算當前時間跟HiredDate的值之間所隔的天數,並把它作為一個字符串返回即可。

  要使用這個方法,我們需要在GridView的TemplateField中使用數據綁定語法來調用它。同樣,我們還是先給GridView添加一個新的模板列。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524336.png

圖十五:給GridView添加一個新的模板列

  將這個新的模板列的頁眉文本(HeaderText)設置成“Days on the Job”,並將其ItemStyle的水平對齊(HorizontalAlign)設置為居中(Center)。要調用DisplayDaysOnJob方法,我們需要給這個模板列添加一個ItemTemplate並加上如下的數據綁定代碼:

<%# DisplayDaysOnJob((Northwind.EmployeesRow)
 ((System.Data.DataRowView) Container.DataItem).Row) %>

  Container.DataItem返回數據源對象中的一個相應的DataRowView對象給GridView。它的Row屬性返回一個強類型化的Nothwind.EmployeesRow,然後再將其傳遞給DisplayDaysOnJob方法。這個數據綁定語法可以直接出現再ItemTemplate(就像下面的代碼中那樣)中或是賦值給Label控件的Text屬性。

  注意:除了傳遞一個EmployeesRow的實例,其實我們也可以僅僅傳遞HireDate的值,使用<%# DisplayDaysOnJob(Eval("HireDate")) %>就可以了。不過呢,Eval方法將返回一個object類型,所以我們就必須要修改DisplayDaysOnJob方法的簽名以使其可以接受一個object類型的參數。我們不能將Eval("HireDate")調用的結果隱式的轉換成一個DateTime類型,因為Employees表的HireDate字段是允許為空的。因此,我們需要使DisplayDaysOnJob方法可以接受一個object類型的參數,並判斷這個參數是不是空值(我們可以使用Convert.IsDBNull(objectToCheck)來完成這個驗證工作),然後再進行後面的操作。

  就是因為這個,所以我還是選擇了傳遞整個EmployeesRow實例。在下一節教程中,我們會看到一個更加合適使用Eval("columnName")來傳遞參數給格式化方法的例子。

  在給我們的GridView添加了模板列並在ItemTemplate中添加了調用DisplayDaysOnJob方法的代碼後,聲明代碼應該是這個樣子:

<asp:GridView ID="GridView1" runat="server"
 AutoGenerateColumns="False" DataKeyNames="EmployeeID"
 DataSourceID="ObjectDataSource1">
 <Columns>
 <asp:TemplateField HeaderText="Name" SortExpression="FirstName">
  <EditItemTemplate>
  <asp:TextBox ID="TextBox1" runat="server"
   Text='<%# Bind("FirstName") %>'></asp:TextBox>
  </EditItemTemplate>
  <ItemTemplate>
  <asp:Label ID="Label1" runat="server"
   Text='<%# Bind("FirstName") %>'></asp:Label>
  <asp:Label ID="Label2" runat="server"
   Text='<%# Eval("LastName") %>'></asp:Label>
  </ItemTemplate>
 </asp:TemplateField>
 <asp:BoundField DataField="Title" HeaderText="Title"
  SortExpression="Title" />
 <asp:TemplateField HeaderText="HireDate"
  SortExpression="HireDate">
  <EditItemTemplate>
  <asp:TextBox ID="TextBox2" runat="server"
   Text='<%# Bind("HireDate") %>'></asp:TextBox>
  </EditItemTemplate>
  <ItemTemplate>
  <asp:Calendar ID="Calendar1" runat="server"
   SelectedDate='<%# Bind("HireDate") %>'
   VisibleDate='<%# Eval("HireDate") %>'>
  </asp:Calendar>
  </ItemTemplate>
 </asp:TemplateField>
 <asp:TemplateField HeaderText="Days On The Job">
  <ItemTemplate>
  <%# DisplayDaysOnJob((Northwind.EmployeesRow)
   ((System.Data.DataRowView) Container.DataItem).Row) %>
  </ItemTemplate>
  <ItemStyle HorizontalAlign="Center" />
 </asp:TemplateField>
 </Columns>
</asp:GridView>

  完成了整節教程之後,頁面在浏覽器中的樣子應該是圖十六的這個樣子。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916524310.png

圖十六:“雇員在公司干了多久“也顯示出來了

總結

在GridView控件中,相對於其他的列控件來說,模板列可以處理更加復雜的數據呈現。模板列主要用於這樣一些情況:

·一個GridView列中需要顯示多個數據列

·使用一個Web控件來展示數據比一段簡單的文本更好

·頁面的輸出取決於綁定到GridView的數據,比如說元數據或者說是數據的重新格式化

除了自定義數據的顯示,模板列也用於編輯和插入數據時的用戶界面的自定義,這個我們在後面的章節中將會講到。

接下來的兩節中,我們會繼續討論模板,我們會先看看在DetailsView中使用模板列的情況。跟著我們再去看看FormView,這玩意兒就是用模板來實現一個更加復雜的呈現,當然,用的是一大堆的字段。 

編程愉快!

關於作者

Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用微軟Web技術。Scott是個獨立的技術咨詢顧問,培訓師,作家,最近完成了將由Sams出版社出版的新作,24小時內精通ASP.NET 2.0。他的聯系電郵為[email protected],也可以通過他的博客http://ScottOnWriting.NET與他聯系。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved