DataList.ItemCommand 事件

xssh913913發表於2007-12-06
 一、方法

1、DataBind

很簡單、最常用的方法。繫結資料用。需要注意的只有一點:執行了這個方法後,DataGrid(由於DataGrid和DataList極為相似,所以下面的介紹雖然是針對DataGrid,但與DataList也相差不遠)裡面所有的顯示繫結資料的控制元件,都會顯示DataSource裡的資料,其餘控制元件也將初始化成.aspx裡設計的狀態。





二、屬性

1、DataSource

有DataBind的地方,就應該有DataSource。如果沒有指定DataSource而執行DataBind,那DataGrid將什麼也不會顯示。

DataSource一般是DataSet、DataTable或者DataView。當然也可以繫結DataReader或者其他實現IEnumerable的類。



2、DataKeyField,DataKeys

當你在DataGrid中定位一行之後,肯定想知道這行在資料表裡的位置,至少有五種方法可以做到這一點,設定DataGrid的DataKeyField就是這幾種方法之一。

DataKeyField一般設定為資料表的Unique欄位(否則就沒意義了),通過DataKey可以得到這一行對應的關鍵欄位的值。

DataKeys是DataKey的集合,通過行的索引來讀取相應行的DataKey。



3、EditItemIndex,SelectedIndex,CurrentPageIndex,SelectedItem

這些屬性都很好理解,看名字就知道是什麼意思,需要注意的是,設定了EditItemIndex或者CurrentPageIndex後需要重新執行DataBind方法(當然,前面提到過,還需要設定DataSource)。



4、Columns

沒什麼好解釋的,Columns就是Columns,列的集合,可以設定列的屬性,包括Visible、HeaderText、FooterText、SortExpression等。

嚴重注意:自動生成的列,是不包含在Columns中的。只有在.aspx中顯示宣告的列和在程式碼中新增的列才會被包含在其中。



5、Items

俗話說,最後的都是最重要的,把Items作為最後一個屬性來介紹,正式基於這樣的理由。

Items是DataGridItem的集合,可以遍歷當前DataGrid中顯示資料的DataGridItem。

5.1、DataGridItem

每一個DataGridItem就是DataGrid中顯示的一行,其中包括:

Header DataGrid 控制元件的標題部分

Item DataGrid 控制元件中的項

AlternatingItem DataGrid 控制元件中的交替項

SelectedItem  DataGrid 控制元件中的選定項(由SelectedIndex設定,通過SelectedItem屬性或者Items[SelectedIndex]來讀取)

EditItem  DataGrid 控制元件中處於編輯狀態的項(由EditItemIndex設定,通過Items[EditItemIndex]來讀取)

Separator  DataGrid 控制元件中項之間的分隔符

Footer  DataGrid 控制元件的腳註部分

Pager  DataGrid 控制元件的頁選擇節

注意,DataGrid的Items屬性中不會包含Header、Footer、Pager這三類DataGridItem的。

5.1.1、DataGridItem的屬性

ItemIndex —— 得到行在Items中的索引

ItemType —— 返回行的型別,也就是上面列出的Header、Item、...、Pager

Cells —— 返回行包含的所有TableCell(不管是顯示宣告的,還是自動生成的,不管是可以看見的,還是隱藏掉的),通過TableCell,可以讀取Cell中顯示的文字、包含的控制元件

嚴重注意:只有BoundColumn列和自動生成列,才可以通過TableCell.Text屬性讀取顯示的文字。HyperLinkColumn、ButtonColumn、EditCommandColumn都需要將目標控制元件轉換成相應的控制元件。

比如:

假設DataGrid的第一列宣告如下

<asp:HyperLinkColumn DataTextField="au_id" HeaderText="au_id" DataNavigateUrlField="au_id" DataNavigateUrlFormatString="Edit.aspx?id={0}"></asp:HyperLinkColumn>

讀取的時候可以用:

//Items[0]表示第一行,Cells[0]表示第一列,Controls[0]表示Cell中的第一個控制元件(也只有這個控制元件可以用)

HyperLink link = (HyperLink)DataGrid1.Items[0].Cells[0].Controls[0]);

Response.Write(link.Text);

至於模板列(TemplateColumn),當然也可以通過DataGrid1.Items[i].Cells[j].Controls[n]來獲取,然後轉換成原來的控制元件型別再操作,但是還有個更好的辦法,就是用FindControl來查詢控制元件。

FindControl是System.Web.UI.Control的方法,可以根據子控制元件ID來查詢子控制元件

比如:

假設DataGrid的某一列宣告如下

<asp:TemplateColumn>

   <ItemTemplate>

      <asp:TextBox Runat="server" ID="txtID" Text='<%# DataBinder.Eval(Container.DataItem,"au_id") %>'>

      </asp:TextBox>

   </ItemTemplate>

</asp:TemplateColumn>

讀取方法:

TextBox txt = (TextBox)DataGrid1.Items[1].FindControl("txtID");

Response.Write(txt.Text);

注意:DataList中是沒有Cell的





三、事件

1、ItemCommand、CancelCommand、DeleteCommand、EditCommand、UpdateCommand

也就是DataGrid中,點選Button、LinkButton後執行的事件,執行的事件取決於按鈕的CommandName。其實最主要的一個是ItemCommand,而後面四個都只是ItemCommand的一小部分,

比如一個按鈕的CommandName為"Cancel",當返回後,首先執行的是ItemCommand事件,然後才是CancelCommand事件。



2、PageIndexChanged

如果你的DataGrid是分頁的,那當你在DataGrid上點選Pager上的1、2、3或者<、>時,就會激發這個事件。

在這個事件裡面,你可以用e.NewPageIndex來讀取要改變的頁,然後賦值給DataGrid的CurrentPageIndex屬性,最後不要忘了,還要設定DataSource,還要執行DataBind。

注意:DataList中沒有這個事件,如果需要在DataList中分頁,可以一段一段的讀取資料,然後把當前段的資料繫結到DataList上。



3、ItemDataBound,ItemCreated

首先要說的是這兩個事件的發生時間。

ItemDataBound嘛,只要執行了DataBind方法,就會馬上激發這個事件。

ItemCreated呢,如果頁面是第一次訪問(Page.IsPostBack = false),那在第一次執行DataBind的時候,會先激發ItemCreated事件,也就是說,執行了DataBind後,首先會用ItemCreated來建立Header行,然後用ItemDataBound來繫結Header行,再用ItemCreated來建立第一行,再呼叫ItemDataBound來繫結第一行,也就是說ItemCreated和ItemDataBound是交替執行的。

頁面返回時,也會執行ItemCreated事件,在Page_Load之前,但是這時候就不會再執行ItemDataBound事件了。

所以,如果你想在DataGrid裡動態新增什麼控制元件,就需要在ItemCreated事件中,而不是在ItemDataBound事件中。





四、程式碼片斷

1、DataGrid顯示雙層表頭

假設你的DataGrid有三列,現在想將前兩列作為"大類1",第三列作為"大類2",現在,你可以在ItemDataBound事件中加入下面的程式碼:

if (e.Item.ItemType == ListItemType.Header)

{

e.Item.Cells[0].ColumnSpan = 2;

e.Item.Cells[0].Text = "大類1</td><td>大類2</td></tr><tr><td>" + e.Item.Cells[0].Text;

}

用這個方法可以為任意新增新行。



2、設定繫結列或者自動生成列的編輯框寬度

請在你的ItemDataBound事件中加入一下程式碼:

if (e.Item.ItemType == ListItemType.EditItem)

{

for (int i = 0; i < e.Item.Cells.Count; i++)

{

TextBox txt = (TextBox)e.Item.Cells[i].Controls[0];

txt.Width = Unit.Pixel(50);

}

}



3、處理在DataGrid中的DropDownList的事件

DropDownList沒有CommandName屬性,所以不能用ItemCommand事件,不過你可以這樣試試:

在DataGrid的模板列中加入的DropDownList控制元件

<asp:DropDownList runat="server" id="ddl" AutoPostBack="True" OnSelectedIndexChanged="ddl_SelectedIndexChanged" />

然後你在.aspx.cs中加入一個函式

protected void ddl_SelectedIndexChanged(object sender, System.EventArgs e) //一定要宣告成protected或者public,不能是private的。

{

  //在這裡就可以加入其他程式碼

}



3.1、在上面的事件中怎樣得到本行其他Cell的值呢?

我們知道,DataGrid完全是一個Table結構的控制元件,DataGrid包含DataGridItem,每個DataGridItem又包含TableCell,那麼,我們就可以在TableCell的某個控制元件中,利用控制元件的Parent來得到TableCell,再利用TableCell的Parent,就可以得到DataGridItem了。

protected void ddl_SelectedIndexChanged(object sender, System.EventArgs e) //一定要宣告成protected或者public,不能是private的。

{

  DropDownList ddl = (DropDownList)sender;

  TableCell cell = (TableCell)ddl.Parent;

  DataGridItem item = (DataGridItem)cell.Parent;

  Response.Write(item.Cells[0].Text);

}



4、怎樣得到Header、Footer、Pager裡的控制元件

方法一:在ItemCreated或者ItemDataBound中,具體程式碼就不在多寫了

方法二:遍歷DataGrid的所有Item(注意,不是遍歷DataGrid1.Items下的Item)

foreach (DataGridItem item in DataGrid1.Controls[0].Controls)

{

  if (item.ItemType == ListItemType.Header)

  {

    //用item.FindControl查詢相應的控制元件

  }

}

大家可能會注意到,這裡有個DataGrid1.Controls[0].Controls,這表示,DataGrid1下,有一個子控制元件,這個子控制元件是DataGridTable型別,他下面才是DataGridItem集合

在DataList中,下面的子控制元件直接就是DataListItem了,而沒有Table:

foreach (DataListItem item in DataList1.Controls)

{

  //....

}

相關文章