我在做测试的时候,就是当我点击CheckBoxList的某一项的时候触发onselectedindexchanged里面的事件,但是我做的时候发现完全不是那么回事,彻底被搞糊涂了。onselectedindexchanged事件里面得到的CheckBoxList的SelectedItem根本不是我点击的那个选项,而是按照某种我不理解的方式顺序选中的,真的糊涂了。希望有明白的朋友不吝指教,为我指点迷津。以下是我写的代码,实在搞不明白了来这里请大神们教诲。
这是我前台代码:
1 <asp:CheckBoxList ID="Chb" runat="server" RepeatDirection="Horizontal" 2 RepeatColumns="3" AutoPostBack="True" 3 onselectedindexchanged="Chb_SelectedIndexChanged"> 4 </asp:CheckBoxList>
这里是后台代码:
protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { bind(); bindrole(); } } //绑定CheckBoxList数据源 public void bind() { Chb.DataTextField = "UserName"; Chb.DataValueField = "ID"; Chb.DataSource = cs.getdd(); Chb.DataBind(); } //根据数据库中的值绑定CheckBoxList是否被选中 public void bindrole() { for(int i=0;i<Chb.Items.Count;i++) { int id = Convert.ToInt32(Chb.Items[i].Value); bool role = cs.GetEnableByID(id); if(role) { Chb.Items[i].Selected = true; } else { Chb.Items[i].Selected = false; } } } //处理事件 protected void Chb_SelectedIndexChanged(object sender, EventArgs e) { //获取点击的项所绑定的值 int id = Convert.ToInt32(Chb.SelectedValue); //获取数据库中的数据,类型为bit if(cs.GetEnableByID(id)) { int a=cs.SetEnable(id, 0); if (a>0) { bind(); bindrole(); } else { Response.Write("<script type='text/javascript'>alert('修改失败');</script>"); } } else { int b=cs.SetEnable(id, 1); if (b>0) { bind(); bindrole(); } else { Response.Write("<script type='text/javascript'>alert('修改失败');</script>"); } } }
MSDN 那里有说明,由于 CheckBoxList 支持多选,如果选定了多个项,则返回索引最小的选定项的值。
如果要你的效果,需要额外处理一下。页面加上控件
<asp:HiddenField runat="server" ID="hf"></asp:HiddenField>
bindrole() 的 for 循环里加上
Chb.Items[i].Attributes.Add("onclick", "document.getElementById('hf').value = this.value;");
Chb_SelectedIndexChanged 事件的
int id = Convert.ToInt32(Chb.SelectedValue);改成 int id = Convert.ToInt32(hf.Value);
您好,我按照您的方法加上去了
Chb.Items[i].Attributes.Add("onclick", "document.getElementById('hf').value=this.value;");
int id = Convert.ToInt32(hf.Value);
然后在调试的时候发现hf的value不是CheckBoxList的值,而是一个固定的值“on”,这点不明白是为什么,不知道您是否有空再给我点指点。
@倒霉蛋_儿: 我本地测试过是可以的。可能是你其他代码有影响,你要先明白原理,再去修改。
Chb.Items[i].Attributes.Add("onclick", "document.getElementById('hf').value=this.value;"); 这个要放在 if(!IsPostBack) 的外面。
if (!IsPostBack) { bind(); bindrole(); } for (int i = 0; i < Chb.Items.Count; i++) { Chb.Items[i].Attributes.Add("onclick", "document.getElementById('hf').value = this.value;"); }
@geass..: 嗯,再次感谢你的回复,原理我明白,就是在每次加载页面的时候呢给这个CheckBoxList控件的每一个item添加一个“onclick”属性,点击这个item的时候把这个item的值赋给hf,这样就实现了每次点击某一个item的时候准确的获取到点击的项的值。是这个样子吧?嘿嘿,错了原谅我吧,我对js就是纯粹的小白。下面是我全部代码,既然在你那里测试的可以,在我这里怎么就会有问题呢。可能我人品有问题吧。哈哈~~有问题不解决心里就一直想着挺别扭的 。对了,我用的是IE10,不知道是不是IE10的问题,不过我用了IETester,也不行!真心凌乱了。
Class1 cs = new Class1(); protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { bind(); bindrole(); } for(int i=0;i<Chb.Items.Count;i++) { Chb.Items[i].Attributes.Add("onclick", "document.getElementById('hf').value = this.value;"); } } public void bind() { Chb.DataTextField = "UserName"; Chb.DataValueField = "ID"; Chb.DataSource = cs.getdd(); Chb.DataBind(); } public void bindrole() { for(int i=0;i<Chb.Items.Count;i++) { int id = Convert.ToInt32(Chb.Items[i].Value); bool role = cs.GetEnableByID(id); if(role) { Chb.Items[i].Selected = true; } else { Chb.Items[i].Selected = false; } } } protected void Chb_SelectedIndexChanged(object sender, EventArgs e) { int id = Convert.ToInt32(hf.Value); if(cs.GetEnableByID(id)) { int a=cs.SetEnable(id, 0); if (a>0) { bind(); bindrole(); } else { Response.Write("<script type='text/javascript'>alert('修改失败');</script>"); } } else { int b=cs.SetEnable(id, 1); if (b>0) { bind(); bindrole(); } else { Response.Write("<script type='text/javascript'>alert('修改失败');</script>"); } } }
@倒霉蛋_儿: 你的SelectedIndexChanged事件有为什么要再调用 bind(); bindrole();
SetEnable 这个方法是什么用的。
而且服务器向客户端输出脚本不建议用 Response.Write,
用ClientScript.RegisterStartupScript(GetType(), "", "alert('你选择的是:" + hf.Value + "')", true);
其实 你这种情况不适合用 checkboxlist,应该用单选的 RadioButtonList
@geass..: SetEnable这个方法就是设置数据库里面一个bit类型的数据,把它设置为0或者1。SelectedIndexChanged事件里面调用那两个函数(bind(); bindrole();)就是在修改数据库中数据后对CheckBoxList控件的状态进行重新绑定。
其实CheckBoxList控件状态是根据数据库中一个bit类型数据进行绑定的,如果这个bit类型数据为1,就把CheckBoxlist控件设置为被选中,否则设置为未选中。所以要在处理之后重新绑定进行更新,不适合用RadioButtonList。
输出脚本用Response.Write确实很不好,首先就会破坏页面的样式,这里也是因为测试随便写的。嘿嘿。
谢谢你的回答了。先把豆子给你再说吧。不知道你听明白没有我的程序?
@倒霉蛋_儿: SelectedIndexChanged事件里面调用那两个函数(bind(); bindrole();)这个是没必要的,ASP.NET控件有VIEWSTATE属性,自动保存回发时的状态,减少访问数据库的次数。即使一定时重新绑定数据,也应该是提交后用URL重新指向这个页面,在 Page_load事件里做绑定,否则用户按下F5就自动提交数据。
其实你这个页面应该设计成 让用户全部选择完再一次性用按钮提交数据,避免页面经常刷新,代码也不会这样复杂。
@geass..: 嗯,这样确实啊,会不停的与数据库交互,给服务器很大负担,不可取,不过就是原本以为这个会和dropdownlist差不多,结果一写发现根本不对,就想搞清楚怎么回事。谢谢你啦。
对于checkboxlist 为了获取全部的选择项,可以用selectitems 试试看
嗯,谢谢你的回复,不过呢,我不是要获取选择项,是想准确的获取到我点击的这一个item的value。不知道这样说你名表没有。