首页 新闻 会员 周边

CheckBoxList的onselectedindexchanged事件处理机制是什么呢?

0
悬赏园豆:20 [已解决问题] 解决于 2012-12-19 14:17

我在做测试的时候,就是当我点击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>");
            }
        }
    }
愉快编程的主页 愉快编程 | 初学一级 | 园豆:145
提问于:2012-12-18 22:38
< >
分享
最佳答案
0

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);

收获园豆:20
geass.. | 小虾三级 |园豆:1821 | 2012-12-19 07:22

您好,我按照您的方法加上去了

Chb.Items[i].Attributes.Add("onclick", "document.getElementById('hf').value=this.value;");
int id = Convert.ToInt32(hf.Value);

然后在调试的时候发现hf的value不是CheckBoxList的值,而是一个固定的值“on”,这点不明白是为什么,不知道您是否有空再给我点指点。

愉快编程 | 园豆:145 (初学一级) | 2012-12-19 11:27

@倒霉蛋_儿: 我本地测试过是可以的。可能是你其他代码有影响,你要先明白原理,再去修改。

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.. | 园豆:1821 (小虾三级) | 2012-12-19 12:03

@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>");
            }
        }
    }
愉快编程 | 园豆:145 (初学一级) | 2012-12-19 13:10

@倒霉蛋_儿: 你的SelectedIndexChanged事件有为什么要再调用  bind(); bindrole();

SetEnable 这个方法是什么用的。

而且服务器向客户端输出脚本不建议用 Response.Write,

用ClientScript.RegisterStartupScript(GetType(), "", "alert('你选择的是:" + hf.Value + "')", true);

其实 你这种情况不适合用 checkboxlist,应该用单选的 RadioButtonList

geass.. | 园豆:1821 (小虾三级) | 2012-12-19 13:44

@geass..: SetEnable这个方法就是设置数据库里面一个bit类型的数据,把它设置为0或者1。SelectedIndexChanged事件里面调用那两个函数(bind(); bindrole();)就是在修改数据库中数据后对CheckBoxList控件的状态进行重新绑定。

其实CheckBoxList控件状态是根据数据库中一个bit类型数据进行绑定的,如果这个bit类型数据为1,就把CheckBoxlist控件设置为被选中,否则设置为未选中。所以要在处理之后重新绑定进行更新,不适合用RadioButtonList。

输出脚本用Response.Write确实很不好,首先就会破坏页面的样式,这里也是因为测试随便写的。嘿嘿。

谢谢你的回答了。先把豆子给你再说吧。不知道你听明白没有我的程序?

愉快编程 | 园豆:145 (初学一级) | 2012-12-19 14:16

@倒霉蛋_儿: SelectedIndexChanged事件里面调用那两个函数(bind(); bindrole();)这个是没必要的,ASP.NET控件有VIEWSTATE属性,自动保存回发时的状态,减少访问数据库的次数。即使一定时重新绑定数据,也应该是提交后用URL重新指向这个页面,在 Page_load事件里做绑定,否则用户按下F5就自动提交数据。

其实你这个页面应该设计成 让用户全部选择完再一次性用按钮提交数据,避免页面经常刷新,代码也不会这样复杂。

geass.. | 园豆:1821 (小虾三级) | 2012-12-19 14:57

@geass..: 嗯,这样确实啊,会不停的与数据库交互,给服务器很大负担,不可取,不过就是原本以为这个会和dropdownlist差不多,结果一写发现根本不对,就想搞清楚怎么回事。谢谢你啦。

愉快编程 | 园豆:145 (初学一级) | 2012-12-19 17:19
其他回答(1)
0

对于checkboxlist 为了获取全部的选择项,可以用selectitems 试试看

chenping2008 | 园豆:9836 (大侠五级) | 2012-12-19 07:27

嗯,谢谢你的回复,不过呢,我不是要获取选择项,是想准确的获取到我点击的这一个item的value。不知道这样说你名表没有。

支持(0) 反对(0) 愉快编程 | 园豆:145 (初学一级) | 2012-12-19 13:11
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册