Asp.net中Repeater中的坑

一.兩層repeater嵌套綁定數據(全採用手寫代碼方式訪問數據庫,沒有用xxxDataSource控件)

        在repeater裏面嵌套一個repeater時,外層repeater可以正常像只使用一個repeater時那樣設置一些屬性事件,但內層repeater你甚至都無法在vs右邊的控件屬性中找到有事件這個選項,這時,我們就需要採用代碼方式來手動爲第二層repeater設置事件以及其它不能正常設置的東西。大致思路就是,給外層repeater綁定itemDataBound事件,在外層repeater的itemDataBound事件中再給內層repeater設置屬性和事件。位置是itemDataBound事件呢,因爲內層repeater就是嵌套在外層repeater的每行中的。

代碼如下:(以下是實現文章的評論回覆功能所使用的兩層repeater

 //外層repeater的itemDataBound事件
protected void NewsDetail_Repeater_comment_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {

            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)

            {

                Repeater rep = e.Item.FindControl("NewsDetail_Repeater_reply") as Repeater;//找到裏層的repeater對象

                DataRowView rowv = (DataRowView)e.Item.DataItem;//找到分類Repeater關聯的數據項

                int commentId = Convert.ToInt32(rowv["id"]); //獲取填充子類的id

                rep.ItemDataBound += new RepeaterItemEventHandler(NewsDetail_Repeater_reply_ItemDataBound);

                BindReplyRepeater(rep, commentId); //綁定內層repeater數據

             //   rep.ItemCommand += new RepeaterCommandEventHandler(NewsDetail_Repeater_reply_ItemCommand);

            }

        }

//內層repeateritemDataBound方法
        protected void NewsDetail_Repeater_reply_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {

            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)

            {

                LinkButton linkButton = e.Item.FindControl("NewsDetail_Btn_reply") as LinkButton;//找到裏層的LinkButton對象

                linkButton.Click += new EventHandler(NewsDetail_Btn_reply_Click);//綁定按鈕的click事件

            }

        }    



二.關於兩層repeater,獲取的內層repeater中某行TextBox的值(用戶輸入的)

剛開始,本打算通過綁定內層repeater的itemcommand事件來做的,再在內層repeater裏面放個button,通過點擊button之後便可以獲取到Textbox的值,想法很美好, 但是一直獲取不到那個Textbox的值,能找到那個TextBox,但獲取的值爲空。想了許久沒明白。最後嘗試把那個textbox的值寫死(不通過用戶輸入),發現這樣竟然可以獲取到這個TextBox的值。現在反過來思考,之前之所以獲取值爲空,說明用戶輸入的值在獲取時本身就是空(儘管用戶輸入了),爲什麼會這樣呢?  這時,我思考了一下,嘗試在Page_load方法中限定只有在第一次頁面加載時(就是除去回傳)才綁定外層repeater數據(綁定外層時同時就綁定了內層),然後在內層repeater的itemcommand事件方法中的最後調用綁定外層repeater的方法(因爲我覺得是因爲頁面執行的順序導致用戶輸入的內容被刷新,想要在itemcommand事件中獲取到用戶的輸入的值之後再綁定repeater的數據,也就是刷新repeater的值)。但這時又出現了一個問題,點擊button按鈕之後並沒有事件觸發。  後來思考了一下,可能是因爲我把綁定repeater的方法放在了itemcommand事件方法內,而itemcommand事件的綁定是在綁定repeater數據時綁定的。所以這樣寫,內層的itemcommand事件並沒有被綁定,也就沒有被執行。

最後發現這種方法不行,就放棄了repeater的itemcommand事件,而是選擇那個內層repeater裏面的那個button的onclick事件,當然,關於repeater的數據綁定方法的放置,和上面一樣,在page_load方法中只有在第一次訪問頁面時才執行,其餘在這個button的click事件方法的最後執行。這樣就能成功獲取到用戶輸入的值了。

protected void NewsDetail_Btn_reply_Click(object sender, EventArgs e)
        {

            string str = (((LinkButton)sender).Parent.FindControl("NewsDetail_replyContent") as TextBox).Text.ToString();//獲取與觸發按鈕linkButton同一行的textBox的值

            string slstr = ((LinkButton)sender).CommandArgument.ToString();

            //string str = e.CommandArgument.ToString();

            string newUrl = "<script>window.οnlοad=function(){alert('" + str+"  "+slstr + "');}</script>";

            Response.Write(newUrl);

            BindCommentRepeater(NewsDetail_Repeater_comment, newsId);
        }

當頁面進行回發時,如點擊按鈕,以上事件都會重新執行一次,這時的執行順序爲: 
1. OnPreInit 
2. OnInit 
3. OnInitComplete 
4. OnPreLoad 
5. Page_Load 
6. OnLoad 
7. Button_Click 
8. OnLoadComplete 
9. OnPreRender

這是爲什麼要把綁定repeater數據的方法放在click事件中的原因(除第一次頁面加載外),因爲如果無條件放在Page_Load方法中,而Page_Load方法總會比Button_click事件先執行,最終永遠獲取不到用戶輸入的文本(在獲取前就被刷新了)。這也驗證了,上面用itemcommand事件時,這樣寫爲什麼不行,因爲itemcommand方法根本沒綁定。

總結:今後不用Asp.net開發,至少不用webform。

發佈了43 篇原創文章 · 獲贊 9 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章