我有一些工作代码,但我不认为这是实现我的目标的最佳途径。
我有一个包含5个项目的CheckBoxList - 4个单独的项目和1个“全选”项目。选择全选后,我希望为用户选中其他4个。取消选择全选后,我希望为用户取消选中其他4个。
我在StackOverflow和Google上发现的一堆东西只是建议通过CheckBoxList.Items循环,但这对我的情况不起作用。例如,假设用户取消选中Item#3 - 这将触发OnSelectedIndexChanged事件,此时我将开始循环遍历Items。我会发现未选中“全选”项,因此我将取消选择所有项目。因此,用户只会检查第3项,以便立即取消它。
下面是我的工作代码,但它使用了一些奇怪的功能,我无法想象这是实现我正在寻找的最佳方式。
protected void StatusCheckBoxListChanged(object sender, System.EventArgs e)
{
//Crazy code I found online to determine which item triggered the event
CheckBoxList list = (CheckBoxList)sender;
string[] control = Request.Form.Get("__EVENTTARGET").Split('$');
int index = control.Length - 1;
ListItem li = (ListItem)list.Items[Int32.Parse(control[index])];
if (li.ToString().Equals("Select All")) //If it was the "Select All" Item which triggered the event
{
//If it was checked, check off everything. If it was unchecked, uncheck everything.
for(int i = 0; i < StatusCheckBoxList.Items.Count; i++)
{
StatusCheckBoxList.Items[i].Selected = StatusCheckBoxList.Items.FindByValue("Select All").Selected;
}
}
}
答案 0 :(得分:1)
您可以尝试向您显示选择全部的上一个值的页面添加字段
bool SelectAll;
在PageLoad
事件处理程序中初始化它,类似这样
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback){
SelectAll = StatusCheckBoxList.Items.Cast<ListItem>().FirstOrDefault(d => d.Text == "Select All" && d.Selected) != null;
}
}
并像这样更改您的活动
protected void StatusCheckBoxListChanged(object sender, System.EventArgs e)
{
if(SelectAll != (StatusCheckBoxList.Items.Cast<ListItem>().FirstOrDefault(d => d.Text == "Select All" && d.Selected) != null)){
SelectAll = !SelectAll;
foreach(var li in StatusCheckBoxList.Items){
li.Selected = SelectAll;
}
}
}
注意:如果您知道具有“全选”值的项目位置,则可以不使用LINQ这样的
“全选”是第一项
时的案例示例protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback){
SelectAll = StatusCheckBoxList.Items[0].Selected;
foreach(var li in StatusCheckBoxList.Items){
li.Selected = SelectAll;
}
}
}
并像这样更改您的活动
protected void StatusCheckBoxListChanged(object sender, System.EventArgs e)
{
if(SelectAll != StatusCheckBoxList.Items[0].Selected){
SelectAll = !SelectAll;
foreach(var li in StatusCheckBoxList.Items){
li.Selected = SelectAll;
}
}
}
答案 1 :(得分:0)
我过去通过设置标志来解决这个问题,例如:
public class MyClass
{
bool _IsReady = true;
protected void StatusCheckBoxListChanged(object sender, System.EventArgs e)
{
if (!_IsReady)
{
return;
}
//Crazy code I found online to determine which item triggered the event
CheckBoxList list = (CheckBoxList)sender;
string[] control = Request.Form.Get("__EVENTTARGET").Split('$');
int index = control.Length - 1;
ListItem li = (ListItem)list.Items[Int32.Parse(control[index])];
if (li.ToString().Equals("Select All")) //If it was the "Select All" Item which triggered the event
{
SetAllStatusItemsSelected(StatusCheckBoxList.Items.FindByValue("Select All").Selected);
}
}
private void SetAllStatusItemsSelected(bool IsSelected)
{
_IsReady = false;
//If it was checked, check off everything. If it was unchecked, uncheck everything.
for(int i = 0; i < StatusCheckBoxList.Items.Count; i++)
{
StatusCheckBoxList.Items[i].Selected = StatusCheckBoxList.Items.FindByValue("Select All").Selected;
}
_IsReady = true;
}
}
我有兴趣知道是否有更优雅的方式。
答案 2 :(得分:-1)
这就是我一直解决这个问题的方式
protected void CheckBoxList1_SelectedIndexChanged(object sender, EventArgs e)
{
CheckBoxList lstBx = (CheckBoxList)sender;
List<ListItem> list = lstBx.Items.Cast<ListItem>().ToList();
string[] control = Request.Form.Get("__EVENTTARGET").Split('$');
int index = Convert.ToInt32(control[control.Length - 1]);
ListItem selectAllControl = list.FirstOrDefault(x => x.Text == "Select All");
ListItem selectAll = list.FirstOrDefault(x => x.Selected && x.Text == "Select All");
if (index == 0)
{
if (selectAll != null)
{
foreach (var item in list)
{
item.Selected = true;
}
}
}
else
{
if (selectAllControl != null)
{
selectAllControl.Selected = false;
}
}
}