Repeater控件裏的大智慧

 

Repeater?一個只會綁定數據並顯示數據的低級控件?哦~誰告訴你的?

Repeater因爲他的靈活性和擴展性很高,備受很多程序員青睞。我的一個.net羣成員曾因爲比較Repeater和GridView而爭得面紅耳赤。我個人也是因爲GridView有些功能無法實現,纔開始研究Repeater的。

當然了,我對GridView也不是太熟悉。無法客觀的比較兩者的優劣,但因爲GridView的高度封裝性註定了他的靈活性不及Repeater,而且Repeater做出來的東西比較“乾淨”(個人覺得)。

本着分享爲原則,特此將自己這段時間的研究成果在年前展現給大家。

這裏我將整合很多Repeater的應用,內容長是一定的(我會盡量以最簡單明瞭的形式展現,我知道讀者希望這樣。因爲我在學別人東西的時候也希望這樣。呵呵)。但每個內容板塊都是可以獨立的。OK,現在就開始了。

目 錄

1.Repeater的嵌套使用

2.Repeater裏的按鈕單擊事件

3.獲取子Repeater裏的控件

4.Repeater裏單選按鈕互斥問題

5.Repeater中記錄單選按鈕選擇狀態並顯示

1.Repeater的嵌套使用:

參考代碼:

前臺:

<asp:Repeater ID="questionTable" runat="server"
onitemdatabound="questionTable_ItemDataBound">
<itemtemplate>
<%#DataBinder.Eval (Container.DataItem ,"FID") %>
<asp:Repeater ID="questionOption" runat="server">
<itemtemplate>
<%#DataBinder.Eval (Container.DataItem ,"OPTIONNAME") %>

</itemtemplate>
</asp:Repeater>
</itemtemplate>
</asp:Repeater>

如果你仔細看了下結構,你是否會思考一個問題。如何對裏面嵌套的Repeater進行數據綁定呢?

接下來看後臺代碼。

後臺:

//用Repeater的ItemDataBound事件

protected void questionTable_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
System.Web.UI.WebControls.Repeater questionOption = (System.Web.UI.WebControls.Repeater)e.Item.FindControl("questionOption"); //獲取嵌套中的Repeater 這是關鍵

//接下來就可以把你的數據源給子Repeater了
questionOption.DataSource = "......" ; //給出要綁定的數據
questionOption.DataBind();
}
}

小結:

什麼時候用嵌套呢?當要綁定的數據存在主子表時,嵌套的Repeater就可以幫大忙了。外面的綁定主表數據,裏面的綁定子表數據。這樣顯示出來的情況是主表記錄顯示一行接着顯示一行子表記錄。以此類推。這是不是給人一種耳目一新的感覺呢?如果是多層嵌套也沒關係,就是不斷獲得子Repeater對象即可。

PS:要主表記錄行下面顯示對應主表的子表記錄,就看你給子Repeater綁定怎樣的數據源了。這裏就是看你如何傳值了,給怎樣的數據源了。

2.Repeater裏的按鈕單擊事件

參考代碼:

前臺:

<asp:Button ID="delete" runat="server" Text="刪除" OnCommand="deletequestionOption_Click"></asp:Button>

後臺:
protected void deletequestionOption_Click(object sender,CommandEventArgs e)
{

if ((sender as System.Web.UI.WebControls.Button).Text == "刪除")
{

//如何獲取控件對象呢,彩色的代碼就是獲取的方法
}
}

小結:

你想過用Repeater來編輯顯示出來的數據嗎?比如刪除或修改數據。在Repeater裏面放入Button。通過OnCommand屬性來產生一個事件,以便達到編輯數據的效果。

3.獲取子Repeater裏的控件

參考代碼:

前臺:

<asp:Repeater ID="questionTable" runat="server"
onitemdatabound="questionTable_ItemDataBound">
<itemtemplate>
<asp:Repeater ID="questionOption" runat="server">
<itemtemplate>
<asp:TextBox ID="option" runat="server" Text='<%#DataBinder.Eval (Container.DataItem ,"OPTIONNAME") %>'></asp:TextBox>
</itemtemplate>
</asp:Repeater>
</itemtemplate>
</asp:Repeater>

後臺:
//ItemCommand事件是Repeater中生成事件時激發(也就是Repeater裏面的事件都會觸發此事件)
protected void questionTable_ItemCommand(object source, RepeaterCommandEventArgs e)
{
System.Web.UI.WebControls.TextBox Toption = null;
string toption = null;

System.Web.UI.WebControls.Repeater rptchild = (System.Web.UI.WebControls.Repeater)e.Item.FindControl("questionOption");

//先獲取子Repeater
for (int j = 0; j < rptchild.Items.Count; j++) //通過循環遍歷來獲取

{
//找到子級Repeater中的控件
Toption = (System.Web.UI.WebControls.TextBox)rptchild.Items[j].FindControl("Toption");
toption = Toption.Text;
}
}

4.Repeater裏單選按鈕互斥問題

有時需要往Repeater中加入單選按鈕,當我們加入<asp:radioButton/>這個控件後,發現無論自己如何設置GroupName屬性也無法使其互斥(每個單選都能被選中)。爲什麼會這樣呢?

這是因爲放入Repeater中的單選按鈕控件自動生成的RadioButton的GroupName不是唯一的,是依據“模板行ID+radiobutton的ID”(如:Repeater1_ctl02_CustomerRadio1,Repeater1_ctl03_CustomerRadio1)

瞭解原因後,所以解決方法有兩種,一種是重寫<asp:radioButton/>控件(重寫,估計你會崩潰的)。令一種就是用<input type="radio"/>來解決。

我選擇最簡單的第二種,真的很簡單。網上有一種方法也用到了<input type="radio"/>但是都用到了大量的JavaScript。很頭疼的說,都挺複雜的。

我們知道<input type="radio"/>分組的屬性是name。所以當你設置name屬性後,就會發現所有行的單選按鈕都互斥(因爲所有的name都相同),正好與<asp:radioButton/>走了另一個方向的極端。所以必須綜合思考下。

我們可以通過獲取Repeater顯示行的行號來表示name,那樣就可以讓每行的單選按鈕互斥了。所以獲取行號的方法如下:

<input type="radio" id="Radio" name="<%#Container..ItemIndex%>"/>

Container.ItemIndex是獲取Repeater的行號

如果你運用了嵌套Repeater,而且你的單選按鈕在子Repeater。那麼你的radio必須獲取父Repeater行號才行。方法如下:

<input type="radio" id="Radio" name="<%#((RepeaterItem)Container.Parent.Parent).ItemIndex%>"/>

5.Repeater中記錄單選按鈕選擇狀態並顯示

爲什麼要記錄,當你的Repeater具有分頁功能的時候。你每次點擊其它的頁面時,會將原來已被選中的radio全部還原成爲選中狀態。所以記錄下每頁的radio選擇情況就很有必要了。這裏用JavaScript來解決。

代碼如下:

function AddRemoveValues(oChk) {
var HdnSelectedValues = document.getElementById("ctl00_cphPostback_HdnSelectedValues"); //這裏隱藏控件的id是通過查看源碼獲得的 原因可能是因爲每個母版也裏面包含了其它自帶的隱藏控件
var names = document.getElementsByName(oChk.name); //這裏是獲取一行中的所有單選按鈕 爲下面來分別判斷那個是被選中的
for (var i = 0; i < names.length; i++)
if (names[i].checked) {
if (HdnSelectedValues.value.indexOf(oChk.value) < 0) { //如果隱藏控件裏面有這個值了,就不進行添加(防止用戶多次點擊已選中的單選按鈕)
HdnSelectedValues.value += "," + oChk.value;
}
}
else {
HdnSelectedValues.value = HdnSelectedValues.value.replace("," + names[i].value, ""); //沒有被選擇,則替換掉原來進去的值
}

}

<input type="radio" id="option" οnclick="AddRemoveValues(this)" value='<%# Eval("FID") %>' name="<%#((RepeaterItem)Container.Parent.Parent).ItemIndex%>"/>
<asp:HiddenField ID="HdnSelectedValues" runat="server" />

延伸:

雖然每次點擊的radio都被記錄了下來。那怎麼樣利用這些記錄的值來顯示出來呢?下面我們就談論這個問題。

同樣通過激發某個事件來激發一個腳本。腳本代碼如下:

function SelectStatus() {
var HdnSelectedValues = document.getElementById("<%=HdnSelectedValues.ClientID%>");
var radios = document.getElementsByTagName("input"); //獲取當前頁面所有的radio

for (var i = 0; i < radios.length; i++) {
if (radios[i].type == "radio") {
if (HdnSelectedValues.value.indexOf(radios[i].value) >= 0) { //如果該單選按鈕的值在隱藏控件裏則單選爲被選狀態
radios[i].checked = true;
}
}
}
}

PS: 值得注意的是,通過“HdnSelectedValues.ClientID”來獲取客戶端ID。比如我這裏查看到源代碼中的客戶端是ID的"ctl00_cphPostback_HdnSelectedValues",這就是爲什麼直接獲取“HdnSelectedValues”是沒用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章