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.onload=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。

猜你喜欢

转载自blog.csdn.net/qq_35268841/article/details/103674524
今日推荐