1. 程式人生 > >asp net夜話之八 資料繫結控制元件

asp net夜話之八 資料繫結控制元件

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

《asp.net夜話》封面

通過前面的例子我們看到每次我們要顯示資料的時候都要通過一個迴圈來顯示滿足條件的資料,這是一個比較麻煩的過程,為此微軟定義了一系列的控制元件專門用於顯示資料的格式,通過這些控制元件可以以視覺化的方式檢視繫結資料之後的效果。這些控制元件稱之為資料繫結控制元件。在asp.net中所有的資料庫繫結控制元件都是從BaseDataBoundControl這個抽象類派生的,這個抽象類定義了幾個重要屬性和一個重要方法:
DataSource屬性:指定資料繫結控制元件的資料來源,顯示的時候程式將會從這個資料來源中獲取資料並顯示。
DataSourceID屬性:指定資料繫結控制元件的資料來源控制元件的ID, 顯示的時候程式將會根據這個ID找到相應的資料來源控制元件,並利用這個資料來源控制元件中指定方法獲取資料並顯示。
DataBind()方法:當指定了資料繫結控制元件的DataSource屬性或者DataSourceID屬性之後,再呼叫DataBind()方法才會顯示繫結的資料。並且在使用資料來源時,會首先嚐試使用DataSourceID屬性標識的資料來源,如果沒有設定DataSourceID時才會用到DataSource屬性標識的資料來源。也就是說DataSource和DataSourceID兩個屬性不能同時使用


資料繫結控制元件的DataSource控制元件屬性必須是一個可以列舉的資料來源,如實現了ICollection、IEnumerable或IListSource介面的類的例項。

今天要講述的內容有:
DropDownList控制元件
ListBox控制元件
GridView控制元件
DataList控制元件
Repeater控制元件

FormView控制元件

DetailsView控制元件

DropDownList控制元件
DropDownList控制元件是一個相對比較簡單的資料繫結控制元件,它在客戶端被解釋成<select></select>這樣的HTML標記,也就是隻能有一個選項處於選中狀態。
DropDownList控制元件常見屬性:
AutoPostBack屬性:這個屬性的用法在講述基本控制元件的時候已經講過,是用來設定當下拉列表項發生變化時是否主動向伺服器提交整個表單,預設是false,即不主動提交。如果設定為true,就可以編寫它的SelectedIndexChanged事件處理程式碼進行相關處理(注意:如果此屬性為false即使編寫了SelectedIndexChanged事件處理程式碼也不會馬上起作用)。
DataTextField屬性:設定列表項的可見部分的文字。
DataValueField屬性:設定列表項的值部分。
Items屬性:獲取控制元件的列表項的集合。
SelectedIndex屬性:獲取或設定 DropDownList 控制元件中的選定項的索引。
SelectedItem屬性:獲取列表控制元件中索引最小的選定項。
SelectedValue屬性:取列表控制元件中選定項的值,或選擇列表控制元件中包含指定值的項。

因為在實際開發中,使用者希望直觀地看見選中哪個選項,而在操作資料庫的時候我們更希望直接以該值對應的編號來操作,利用DataTextField屬性和DataValueField屬性就可以很方便地做到這一點,這兩個屬性通常是資料來源中的某個欄位名(如果DataSource屬性是DataTable或者是DataView的話)或者範型集合中實體的屬性(如果DataSource屬性是System.Collections.Generic.List<T>的話,則可以指定為T的屬性)。
下面是DropDownList控制元件的例子,依然用到的是第六章中建立的表(本程式碼採用了單頁模式):

 

 

 

注意,第二個DropDownList控制元件繫結資料來源時有兩句話必不可少,就是:

 

 

 

 

 

 

 

另外,DropDownList控制元件預設情況下是第一個選項處於選中狀態,如果我們想在繫結資料之後讓某個選項處於選中狀態,可以利用它的Items屬性,DropDownList控制元件的Items屬性其實是一個ListItemCollection的例項,ListItemCollection類有兩個重要方法:

public ListItem FindByText (string text):在選項集合中查詢指定文字的選項。

public ListItem FindByValue (string value) :在選項集合中查詢指定值的選項。

利用這個屬性,我們可以讓某個選項在資料繫結後就處於選中狀態。比如在上面的程式碼中我們希望繫結資料來源後,讓劉備處於選中狀態,那麼我們的BindUserList()的程式碼可以這麼寫:

 

 

 

 

 

 

 

ListBox控制元件

ListBox控制元件和DropDownList控制元件非常類似,ListBox控制元件是也是提供一組選項供使用者選擇的,只不過DropDownList控制元件只能有一個選項處於選中狀態,並且每次只能顯示一行(一個選項),而ListBox控制元件可以設定為允許多選,並且還可以設定為顯示多行。

除了與DropDownList具有很多相似的屬性之外,ListBox控制元件還有以下屬性:

Rows屬性:設定ListBox控制元件顯示的行數。

SelectionMode屬性:設定ListBox的選擇模式,這是一個列舉值,它有MultipleSingle兩個值,分別代表多選和單選,預設是Single,即同時只能有一個選項處於選中狀態。如果要想實現多選,除了設定SelectionMode屬性為Multiple外,在選擇時需要按住Ctrl鍵。

需要說明的是,因為ListBox允許多選,所以如果ListBoxSelectionMode屬性為Multiple,那麼SelectedIndex屬性指的是被選中的選項中索引最小的那一個,SelectedValue屬性指的是被選中的選項集合中索引最小的那一個的值。

 

下面是ListBox的用法舉例:

 

 

 

 

 

按住Ctrl鍵同時選擇幾個選項,然後點選“確定”按鈕之後的結果:

 

 

 

 

GridView控制元件

GridView控制元件作為asp.net1.1下的DataGrid的替代品,它內建了表格呈現樣式。GridView 控制元件用來在表中顯示資料來源的值。每列表示一個欄位,而每行表示一條記錄。GridView 控制元件支援下面的功能:

繫結至資料來源控制元件,如 SqlDataSource

內建排序功能。

內建更新和刪除功能。

內建分頁功能。

內建行選擇功能。

以程式設計方式訪問 GridView 物件模型以動態設定屬性、處理事件等。

多個鍵欄位。

用於超連結列的多個數據欄位。

可通過主題和樣式進行自定義的外觀。

可以實現多種樣式的資料展示。

GridView控制元件主要有以下常見屬性:

AllowPaging屬性:設定是否啟用分頁功能。

AllowSorting 屬性:設定是否啟用排序功能。

AutoGenerateColumns 屬性:設定是否為資料來源中的每個欄位自動建立繫結欄位。這個屬性預設為true,但在實際開發中很少會自動建立繫結列,我們總會根據一些情況讓一些列不顯示,比如顯示使用者列表的時候不會將使用者密碼顯示出來,顯示文章列表的時候不會將文章內容顯示出來。

Columns屬性:獲取 GridView 控制元件中列欄位的集合。

PageCount屬性:獲取在 GridView 控制元件中顯示資料來源記錄所需的頁數。

PageIndex屬性:獲取或設定當前顯示頁的索引。

PagerSetting屬性:設定GridView的分頁樣式。

PageSize屬性:設定GridView控制元件每次顯示的最大記錄條數。

下圖是將一個GridView控制元件拖到頁面的情況:

 

點選“編輯列”會出現下面的介面:

 

 

從上面的圖中我們可以看出在GridView中可以顯示7中型別的欄位,它們分別是:

BoundField:繫結欄位,以文字的方式顯示資料。

CheckBoxField:複選框欄位,如果資料庫是bit欄位,則以此方式顯示。

HyperLinkField:用超級連線的形式的顯示欄位值。

ImageField:用於顯示存放Image圖象的url欄位資料,顯示成圖片效果。

ButtonField:顯示按鈕列。

CommandField:顯示可執行操作的列,可以執行編輯或者刪除等操作。可以設定它的ButtonType屬性來決定顯示成普通按鈕、圖片按鈕或者超級連結。

TemplateField:自定義資料的顯示方式,在這裡我們可以使用我們所熟悉的HTML控制元件或者asp.net Web伺服器控制元件。

對於我們經常使用到的Users這個表,這次我們不再使用for迴圈來顯示了,這次使用GridView控制元件來顯示。GridView控制元件的欄位大都有HeaderText這個屬性,這個屬性是用來設定資料的鏢頭的,如果我們不設定的話預設都是以資料庫的相應欄位作為表頭。另外還有一個DataField屬性,這個屬性是用來設定要繫結顯示的資料的屬性或者列名。在這裡我們希望在顯示的時候給出一個連結,使用者可以點選這個連結跳轉到檢視詳細介紹的頁面,並且我們還希望將使用者的電子郵件顯示成超級連結的方式。

在這裡還需要介紹一個屬性:DataNavigateUrlFormatString,類似的還有DataTextFormatString,有時候在顯示資料的時候我們並不希望僅僅將資料簡簡單單顯示,還希望用一定的格式來顯示,那麼就可以設定這個屬性,在顯示的時候我們用到了一個HyperLinkField,用來顯示一個超級連結,它的設定如下:

DataNavigateUrlFormatString屬性的值為"ShowUser.aspx?UserId={0}",而DataNavigateUrlFields屬性的值為"UserId",也就是將來顯示每行資料的時候都會將該行對應的“UserId”欄位的值替換{0},類似於string.Format("ShowUser.aspx?UserId={0}"[“UserId”]的值)

 

 

 

 

 

對於電子郵件的顯示,我們發現BoundFieldCheckBoxFieldHyperLinkFieldImageFieldButtonFieldCommandField欄位都較難實現或者根本不可能實現我們的要求,這時可以使用TemplateField這種型別的欄位。

GridView控制元件中TemplateField欄位中可以定義5中不同型別的模版,分別如下:

AlternatingItemTemplate:交替項模版,即偶數項中顯示的內容,可以進行資料繫結。

EditItemTemplate:編輯項模版,噹噹前這條資料處於編輯狀態的時候要顯示的內容,可以進行資料繫結。

FooterTemplate:腳模版,即腳註部分要顯示的內容,不可以進行資料繫結。

HeaderTemplate:頭模版,即表頭部分要顯示的內容,不可以進行資料繫結。

ItemTemplate:項模版,處於普通項中要顯示的內容,如果指定了AlternatingItemTemplate中的內容,則這裡的設定是奇數項的顯示效果。可以進行資料繫結。

注意:可以不設定AlternatingItemTemplate,如果沒有設定AlternatingItemTemplate,那麼所有的資料項在非編輯模式下都按照ItemTemplate中的設定顯示。

下面是用分頁顯示Users表中的資料的例子,對於奇數行使用者的電子郵件僅僅顯示電子郵件地址,偶數行的使用者顯示為超級連結。以下是程式碼:

 

 

 

 

 

 

點選第二頁的效果:

 

對於GridView的用法筆者要說明幾點:

1、上面的程式碼採用了預設的自定義分頁,這種分頁每次翻頁的時候都會將所有的資料全部從資料中取出來,根據當前頁索引和每頁要顯示的記錄條數決定要顯示哪些記錄,其它的資料會被丟棄掉,在資料量比較大的時候會導致效能低下。對於表中有大量資料的情況,需要自已寫分頁方法,每次只從資料庫中取出需要顯示的資料,提高網站的效能,並且根據當前頁索引顯示頁面跳轉導航連結,關於如何分頁查詢在本系列文章中ADO.NET部分筆者已經講過,這裡不再贅述。

2、當DataSource中沒有任何記錄時,GridView預設是沒有任何顯示的。我們還可以給GridView新增一種效果,即當GridView中沒有任何資料時給使用者提示。這個可以通過給GridView新增EmptyDataTemplate模版,定義沒有資料資料時顯示的內容,對上面的GridView我們給它新增如果沒有資料的功能。在<asp:GridView></asp:GridView>新增如下內容:<EmptyDataTemplate>溫馨提示:當前沒有任何記錄哦。</EmptyDataTemplate>,這時GridView的定義如下:

 

 

 

 

 

 

 

3、如果當前的項顯示樣式不符合我們的要求的時候,我們可以設定項的顯示樣式,如下圖:

 

 

4

注意:在本例中資料繫結時都加了if (!Page.IsPostBack)這種判斷,這樣做的目的是不會因為某個控制元件的提交頁面導致整個頁面的重新繫結,絕大部分情況下這種重新資料繫結是沒有必要的、而且會影響網站的效率的。在實際開發中,各位朋友要區分這一情況。

 

GridView中實現反選和全選功能

在顯示資料的時候經常有一些批量操作的功能,比如資料的批量刪除等,我們可以利用javascript指令碼來輔助實現這一功能,不過如果用asp.net中的CheckBox控制元件來實現這個功能的話,比較麻煩,因為在GridView這樣的控制元件將asp.net中的Web伺服器控制元件轉換成普通HTML控制元件的時候不能直接按照控制元件的ID來分配,存在著在一個GridView中有多個CheckBox控制元件,為了防止命名衝突,asp.net 為頁上的各個伺服器控制元件自動生成一個唯一的 ClientID 值。ClientID 值是通過連線控制元件的 ID 值和它的父控制元件的 UniqueID 值生成的。如果未指定控制元件的 ID 值,則使用自動生成的值。如果我們在GridView中新增一個CheckBox控制元件,我們在生成的HTML控制元件中會發現它生成的HTML程式碼類似於下面的格式:

 

javascript操作GridView這樣的控制元件中的asp.net Web伺服器控制元件一定要注意這個情況,可以通過asp.net Web伺服器控制元件的ClientID屬性來操作。

 

 

 

 

 

這時候我們可以使用普通HTML控制元件來達到我們想要的功能,asp.net對於普通HTML控制元件是不會更改它的idname屬性的。

實現了單選和複選功能之後,我們如何獲取選中的值呢?因為是普通HTML控制元件,自然不能像asp.net Web伺服器控制元件那樣利用某個屬性來判斷,不過我們可以利用一個asp.net Button伺服器控制元件來提交表單,然後通過Request[“控制元件的name”]來獲取選中的值(沒有印象的朋友趕緊看第三頁的介紹),得到值是形如“15,16,17”這樣的字串,這時我們可以利用SQL語句來進行批量操作,我們的SQL語句可以這麼寫:

String sql=”delete from Users where UserId in(“+Request["CheckboxGroup"]+”)”;

這樣就不必進行分割字串的操作,只連線資料庫操作就刪除了選中的資料,大大提高了效率。

因為整個程式的程式碼比較複雜,所以採用了頁面和程式碼分離的模式,前臺程式碼如下:

 

 

 

 

 

 

 

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. using System.Data.SqlClient;
  12. public partial class MultiSelectGridView : System.Web.UI.Page
  13. {
  14.     protected void Page_Load(object sender, EventArgs e)
  15.     {
  16.         if (!Page.IsPostBack)
  17.         {
  18.             BindGridView(0);
  19.         }
  20.     }
  21.     //指定繫結頁面的資料
  22.     private void BindGridView(int pageIndex)
  23.     {
  24.         //例項化Connection物件
  25.         SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
  26.         //例項化Command物件
  27.         SqlCommand command = new SqlCommand("select * from UserInfo", connection);
  28.         SqlDataAdapter adapter = new SqlDataAdapter(command);
  29.         DataTable data = new DataTable();
  30.         adapter.Fill(data);
  31.         gvUserList.DataSource = data;
  32.         gvUserList.PageIndex = pageIndex;//設定當前顯示第幾頁
  33.         gvUserList.DataBind();
  34.     }
  35.     //翻頁事件
  36.     protected void gvUserList_PageIndexChanging(object sender, GridViewPageEventArgs e)
  37.     {
  38.         //指定新頁面,重新繫結資料
  39.         BindGridView(e.NewPageIndex);
  40.     }
  41.     //刪除選中的使用者程式碼
  42.     protected void btnDelete_Click(object sender, EventArgs e)
  43.     {
  44.         string sql = "delete from UserInfo where UserId in (" + Request["CheckboxGroup"] + ")";
  45.         SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
  46.         SqlCommand command = new SqlCommand(sql, connection);
  47.         connection.Open();
  48.         int count = command.ExecuteNonQuery();
  49.         connection.Close();
  50.         //刪除成功後給出提示,並且跳轉到當前頁面
  51.         if (count > 0)
  52.         {
  53.             Page.ClientScript.RegisterClientScriptBlock(
  54.                 this.GetType(), "success",
  55.                 "<script language='javascript'>alert('刪除成功!');"
  56.             + "window.location='MultiSelectGridView.aspx';</script>"
  57.                 );
  58.         }
  59.         else//刪除不成功給出不成功的提示
  60.         {
  61.             Page.ClientScript.RegisterClientScriptBlock(
  62.                 this.GetType(), "fail",
  63.                 "<script language='javascript'>alert('刪除成功!');</script>"
  64.                 );
  65.         }
  66.     }
  67. }

頁面的初始執行效果:

 

 

 

 

 

 

當一個也沒有選擇的時候點“刪除”按鈕之後的效果:

 

 

當選中一部分之後再點選“刪除”的效果:

 

 

點選“確定”之後就會刪除所有處於選中狀態的使用者,並且彈出刪除成功的提示框,使用者點選確定又會跳轉到當前頁面,顯示刪除選中使用者之後的效果。

對上面的程式作如下說明:

1、在頁面的前臺程式碼中使用了幾個javascript函式用於實現全選、反選和判斷使用者是否選擇了至少一項及刪除確認對話方塊的功能,“var checkbox = document.all.CheckboxGroup;”這句程式碼的作用是獲取當前頁面中所有name”CheckboxGroup”HTML控制元件,而我們在GridView中所有的實現選擇的複選框的name屬性就是”CheckboxGroup”

2、在GridView中可以使用普通HTML控制元件或者asp.net伺服器控制元件,並且可以對它們的值或者某個屬性進行繫結。

 

DataList控制元件

DataList是一個相對複雜一點的資料繫結控制元件,它需要使用者自己定義資料的展現格式,也就是需要在html層控制資料的展示格式。和GridView控制元件每行只能顯示一條記錄不同,DataList可以在一行顯示多條記錄。

DataList支援以下模版:AlternatingItemTemplateEditItemTemplateFooterTemplateHeaderTemplateItemTemplateSelectedItemTemplateSeparatorTemplate。其中AlternatingItemTemplateEditItemTemplateFooterTemplateHeaderTemplateItemTemplateTemplateField的支援的模版型別時已經介紹了,SelectedItemTemplatem模版是當該項處於選中狀態的效果,SeparatorTemplate是各項之間分隔顯示效果。

DataList有兩個重要屬性,如下:

RepeatColumnsDataList中要顯示的列數。預設是0,即按照RepeatDirection的設定單行或者單列顯示資料。

RepeatDirectionDataList的顯示方式,這個屬性是一個列舉值,有HorizontalVertical兩個值,分別代表水平和垂直顯示。

在使用DataList時經常會巢狀繫結,所謂巢狀就是在一個數據繫結控制元件中巢狀著另一個數據繫結控制元件。下面演示一下DataList進行巢狀繫結的效果。在這個效果裡,首先將UserInfo表中的資料按照性別分類,然後在每種性別裡分別跳出三個使用者顯示。

首先向頁面中新增一個DataList控制元件,如下圖:

 

點選“模版”,在它的ItemTemplate模版中再新增一個Label控制元件和一個DataList控制元件,如下圖:

 

對上述操作生成的前臺程式碼我們做一些修改,如下:

 

 

 

 

 

 

  1. using System;
  2. using System.Data;
  3. using System.Configuration;
  4. using System.Collections;
  5. using System.Web;
  6. using System.Web.Security;
  7. using System.Web.UI;
  8. using System.Web.UI.WebControls;
  9. using System.Web.UI.WebControls.WebParts;
  10. using System.Web.UI.HtmlControls;
  11. using System.Data.SqlClient;
  12. public partial class DataListDemo : System.Web.UI.Page
  13. {
  14.     protected void Page_Load(object sender, EventArgs e)
  15.     {
  16.         if (!Page.IsPostBack)
  17.         {
  18.             BindSex();
  19.         }
  20.     }
  21.     //繫結頂級專案
  22.     private void BindSex()
  23.     {
  24.         SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
  25.         SqlCommand command = new SqlCommand("select distinct sex from UserInfo", connection);
  26.         SqlDataAdapter adapter = new SqlDataAdapter(command);
  27.         DataTable data = new DataTable();
  28.         adapter.Fill(data);
  29.         DataList1.DataSource = data;
  30.         DataList1.DataBind();
  31.     }
  32.     //當繫結DataList1中的每一項時的處理方法
  33.     protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
  34.     {
  35.         //如果要繫結的項是交替項或者是普通項
  36.         //注意此外還有腳模板和腳模版
  37.         if (e.Item.ItemType == ListItemType.Item ||
  38.              e.Item.ItemType == ListItemType.AlternatingItem)
  39.         {
  40.             //e.Item表示當前繫結的那一行
  41.             //利用e.Item.FindControl("Label1")來找到那一行的id為"Label1"的Label控制元件
  42.             Label lbSex = (Label)(e.Item.FindControl("Label1"));
  43.             //利用e.Item.FindControl("Label1")來找到那一行的id為"Label1"的Label控制元件
  44.             DataList dl2 = (DataList)(e.Item.FindControl("DataList2"));
  45.             bool male = bool.Parse(lbSex.Text);
  46.             dl2.DataSource = GetDataTable(male);
  47.             dl2.DataBind();
  48.         }
  49.     }
  50.     /// <summary>
  51.     /// 根據性別來查詢符合條件的使用者
  52.     /// </summary>
  53.     /// <param name="male">是否為男性</param>
  54.     /// <returns></returns>
  55.     private DataTable GetDataTable(bool male)
  56.     {
  57.         SqlConnection connection = new SqlConnection("Data Source=(local);Initial Catalog=AspNetStudy;Persist Security Info=True;User ID=sa;Password=sa");
  58.         SqlCommand command = new SqlCommand("select top 3 RealName from UserInfo where [email protected] order by UserID", connection);
  59.         command.Parameters.AddWithValue("@Sex", male);//新增SqlParameter引數
  60.         SqlDataAdapter adapter = new SqlDataAdapter(command);
  61.         DataTable data = new DataTable();
  62.         adapter.Fill(data);
  63.         return data;
  64.     }
  65. }

頁面的最後執行效果:

 

 

 

 

 

對上面的程式程式碼作幾點說明:

1)在上面的程式碼中使用了兩個DataList控制元件,其中第二個是位於第一個的ItemTemplate模版裡面,這個用於繫結符合當前項中條件的資料,並且我們在第一個的ItemTemplate裡面還用到了一個Label控制元件,這個Label是不可見的(Visible="false"),使用這個控制元件並不是為了顯示資料,而是為了儲存第二個DataList要繫結顯示的資料的條件。在這裡我們是以性別作為頂級分類的,其實這個沒有必要在資料庫查詢並進行繫結顯示,這裡只是通過這種方法來演示DataList如何進行巢狀繫結。

2)在巢狀繫結的時候我們利用了DataListItemDataBound事件,在繫結DataList中的每一項時候都會激發這個事件,當要繫結的項是普通項或者是交替項時,項模版裡就有要顯示子資料的DataList控制元件和我們隱藏Label控制元件,我們利用FindControl()方法找到這兩個控制元件,利用LabelText屬性值作為條件去資料庫查詢滿足條件的資料,並將返回的資料來源繫結到第二個DataList上,這樣就完成了DataList