C#中的ListView添加记录时会引发ItemChecked事件,怎么办? 插入记录前调用BeginUpdate完事调用EndUpdate 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 或者更简单的办法,你就定义一个全局的bool变量,在事件里判断这个变量如果是true,就直接return然后你在需要代码改动控件的地方,改动之前,设置它为true,加载完毕,设置它为false这样即使引发了事件,不走代码不就得了 之前就是那样写的,没用啊看我的代码: listView1.ItemChecked -= listView1_ItemChecked; listView1.BeginUpdate(); listView1.Items.Clear(); for (int i = 0; i < Info.Length; i++) { ListViewItem it = new ListViewItem(); it.Checked = Info[i].Checked; it.Text = Info[i].name; listView1.Items.Add(it); } listView1.EndUpdate(); listView1.ItemChecked += listView1_ItemChecked; 可能不行,因为我发现ItemChecked引发好像不是同步的,而是异步的,也就是添加代码早就执行完了,上面的EndUpdate();也早过了ItemChecked才到 加个flag,不是最简单的么不然用个插件http://www.c-sharpcorner.com/UploadFile/anavijai/programmatically-disable-event-firing-on-list-item-update-in/http://www.codeproject.com/Articles/623579/Temporarily-disable-event-handler 1.如我楼上说的,c#感觉不是同执行这件事的,Event出现得过晚,都晚过了前面所有代码2.我上面写的listView1.ItemChecked -= listView1_ItemChecked;是我猜测的临时禁用Event的代码,不知道对不对? 不同步?不可能吧我在ItemChecked里面加了两秒Sleep,Item.Add下面的代码就在那里等了两秒完全按顺序执行的add beginitem checked: Falseitem checked: Trueadd end-= 确实是取消掉 evenhandler先取消掉,然后再加回去,也是没问题的Debug.WriteLine("add begin"); listView1.ItemChecked -= listView1_ItemChecked; ListViewItem it = new ListViewItem(); it.Text = "abc"; it.Checked = true; listView1.Items.Add(it); listView1.ItemChecked += listView1_ItemChecked; Debug.WriteLine("add end"); 我是调试时得出的结论listView1.ItemChecked += listView1_ItemChecked; 都执行了,ItemChecked都还没执行到 有什么问题么?private void button1_Click(object sender, EventArgs e) {// 造数据 List<MyInfo> Info = new List<MyInfo>(); for (int i = 0; i < 10; i++) { MyInfo myInfo = new MyInfo() { Checked=true, name="Item_" + i }; Info.Add(myInfo); } Debug.WriteLine("add begin:" + DateTime.Now.ToString("HH:mm:ss.fff")); listView1.ItemChecked -= listView1_ItemChecked; listView1.BeginUpdate(); listView1.Items.Clear(); Debug.WriteLine("clear end:" + DateTime.Now.ToString("HH:mm:ss.fff")); for (int i = 0; i < Info.Count; i++) { ListViewItem it = new ListViewItem(); it.Checked = Info[i].Checked; it.Text = Info[i].name; listView1.Items.Add(it); } listView1.EndUpdate(); listView1.ItemChecked += listView1_ItemChecked; Debug.WriteLine("add end:" + DateTime.Now.ToString("HH:mm:ss.fff")); }private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e) { // 故意延长ItemChecked事件的时间 Thread.Sleep(1000); Debug.WriteLine("ItemChecked : " + e.Item.Checked + "-->" + DateTime.Now.ToString("HH:mm:ss.fff")); }输出的Log:add begin:16:44:27.775clear end:16:44:27.806add end:16:44:27.806一瞬间就结束了,顺序也没问题如果,把 -= +=那两行注掉,ItemChecked事件触发add end直到所有的ItemChecked处理完才执行add begin:16:46:39.074clear end:16:46:39.091ItemChecked : False-->16:46:40.107ItemChecked : True-->16:46:41.078ItemChecked : False-->16:46:42.093ItemChecked : True-->16:46:43.099ItemChecked : False-->16:46:44.140ItemChecked : True-->16:46:45.142ItemChecked : False-->16:46:46.130ItemChecked : True-->16:46:47.142ItemChecked : False-->16:46:48.144ItemChecked : True-->16:46:49.174ItemChecked : False-->16:46:50.174ItemChecked : True-->16:46:51.160ItemChecked : False-->16:46:52.179ItemChecked : True-->16:46:53.181ItemChecked : False-->16:46:54.195ItemChecked : True-->16:46:55.211ItemChecked : False-->16:46:56.242ItemChecked : True-->16:46:57.273ItemChecked : False-->16:46:58.244ItemChecked : True-->16:46:59.246add end:16:46:59.255 有什么问题么?private void button1_Click(object sender, EventArgs e) {// 造数据 List<MyInfo> Info = new List<MyInfo>(); for (int i = 0; i < 10; i++) { MyInfo myInfo = new MyInfo() { Checked=true, name="Item_" + i }; Info.Add(myInfo); } Debug.WriteLine("add begin:" + DateTime.Now.ToString("HH:mm:ss.fff")); listView1.ItemChecked -= listView1_ItemChecked; listView1.BeginUpdate(); listView1.Items.Clear(); Debug.WriteLine("clear end:" + DateTime.Now.ToString("HH:mm:ss.fff")); for (int i = 0; i < Info.Count; i++) { ListViewItem it = new ListViewItem(); it.Checked = Info[i].Checked; it.Text = Info[i].name; listView1.Items.Add(it); } listView1.EndUpdate(); listView1.ItemChecked += listView1_ItemChecked; Debug.WriteLine("add end:" + DateTime.Now.ToString("HH:mm:ss.fff")); }private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e) { // 故意延长ItemChecked事件的时间 Thread.Sleep(1000); Debug.WriteLine("ItemChecked : " + e.Item.Checked + "-->" + DateTime.Now.ToString("HH:mm:ss.fff")); }输出的Log:add begin:16:44:27.775clear end:16:44:27.806add end:16:44:27.806一瞬间就结束了,顺序也没问题如果,把 -= +=那两行注掉,ItemChecked事件触发add end直到所有的ItemChecked处理完才执行add begin:16:46:39.074clear end:16:46:39.091ItemChecked : False-->16:46:40.107ItemChecked : True-->16:46:41.078ItemChecked : False-->16:46:42.093ItemChecked : True-->16:46:43.099ItemChecked : False-->16:46:44.140ItemChecked : True-->16:46:45.142ItemChecked : False-->16:46:46.130ItemChecked : True-->16:46:47.142ItemChecked : False-->16:46:48.144ItemChecked : True-->16:46:49.174ItemChecked : False-->16:46:50.174ItemChecked : True-->16:46:51.160ItemChecked : False-->16:46:52.179ItemChecked : True-->16:46:53.181ItemChecked : False-->16:46:54.195ItemChecked : True-->16:46:55.211ItemChecked : False-->16:46:56.242ItemChecked : True-->16:46:57.273ItemChecked : False-->16:46:58.244ItemChecked : True-->16:46:59.246add end:16:46:59.255嗯,你的看上去是没问题,看我的结果,我把你的代码放到我的程序里的结果,明显和你的不一样啊:不过,我的填充数据的地方和你不一样,不是click,而是tab页切换tab1_Selected里做的,按理应该差不多呀麻烦再帮我想想是啥原因?add begin:10:05:19.617clear end:10:05:19.743add end:10:05:19.758ItemChecked : False-->10:05:20.810ItemChecked : True-->10:05:21.812ItemChecked : False-->10:05:22.815ItemChecked : True-->10:05:23.817ItemChecked : False-->10:05:24.819ItemChecked : True-->10:05:25.871ItemChecked : False-->10:05:26.873ItemChecked : True-->10:05:27.875ItemChecked : False-->10:05:28.876ItemChecked : True-->10:05:29.879ItemChecked : False-->10:05:30.880ItemChecked : True-->10:05:31.882ItemChecked : False-->10:05:32.884ItemChecked : True-->10:05:33.886ItemChecked : False-->10:05:34.887ItemChecked : True-->10:05:35.890ItemChecked : False-->10:05:36.892ItemChecked : True-->10:05:37.894ItemChecked : False-->10:05:38.896ItemChecked : True-->10:05:39.901 你用的是标准控件么?我放在tabcontrol的selected事件里面,也是好的啊 你的ListView是不是隐藏的啊?add end完了,才设置 Visible= true的?这样的话,ItemChecked会在add end之后出现,也就是Visible=true那句话的时候触发 绝对是标准控件,不过我把工程集改成.net2.0了,不知道这会影响不?我开个新工程也再试试,看能不能找到原因 不是,它是一直显示着的,此listview是tab页中的不过你这么说的话,我是在tab的selected里面做,也就是切过来的时候,不知道那时候listview算是显示的不? 你把事件 删除掉,也会出 ItemChecked 的log么? 注掉:Debug.WriteLine("ItemChecked : " + e.Item.Checked + "-->" + DateTime.Now.ToString("HH:mm:ss.fff"));就没了,为啥这么问:) 说明有效果啊,你就不用纠结哪个先执行,哪个后执行了只要 你的 tabSelected里面 最开始: -=中间做你自己的操作: Items.add函数最后: +=按这个顺序执行,没有 ItemChecked:xxxxxxxxxxxx 的Log出来,不就达到目的了么 我的修改方式并没有改代码,只是把tab从palne里移出来而已,这样就好了,奇怪吧? tabControl1_Selectedadd begin:15:42:14.876clear end:15:42:14.878add end:15:42:14.881ItemChecked : False-->15:42:14.990ItemChecked : True-->15:42:15.092ItemChecked : False-->15:42:15.194ItemChecked : True-->15:42:15.296tabControl1_SelectedIndexChangedadd begin:15:42:15.302clear end:15:42:15.303ItemChecked : False-->15:42:15.405ItemChecked : True-->15:42:15.507ItemChecked : False-->15:42:15.608ItemChecked : True-->15:42:15.709add end:15:42:15.710终于搞明白了,看上面的数据如果在tab的selected事件里做,就变成异步的了,如果在SelectedIndexChanged事件里做,就变成同步的了,只能说这是ms框架的设计了,好奇怪……………… 呃……我今天用的就是selected事件,同步的 C# winform的datagridview可以实现下表的样式吗? 如何检测别的软件打开时读取了哪些硬件信息? 初学,常量 byte[] 不能初始化时赋值吗? 权限控制的设计 求代码,急,在线等。。。马上给分! crystalReportViewer1控件的问题 访问excel 关于C#的几本入门书,过来人进来说说 如何能利用c#语言屏蔽高级的系统热键CTRL+Alt+Delete 求大神指导,怎么改这个错! wpf datagrid binding 问题 Format问题。
然后你在需要代码改动控件的地方,改动之前,设置它为true,加载完毕,设置它为false
这样即使引发了事件,不走代码不就得了
之前就是那样写的,没用啊看我的代码:
listView1.ItemChecked -= listView1_ItemChecked;
listView1.BeginUpdate();
listView1.Items.Clear();
for (int i = 0; i < Info.Length; i++)
{
ListViewItem it = new ListViewItem();
it.Checked = Info[i].Checked;
it.Text = Info[i].name;
listView1.Items.Add(it);
}
listView1.EndUpdate();
listView1.ItemChecked += listView1_ItemChecked;
可能不行,因为我发现ItemChecked引发好像不是同步的,而是异步的,也就是添加代码早就执行完了,上面的EndUpdate();也早过了
ItemChecked才到
http://www.c-sharpcorner.com/UploadFile/anavijai/programmatically-disable-event-firing-on-list-item-update-in/http://www.codeproject.com/Articles/623579/Temporarily-disable-event-handler
1.如我楼上说的,c#感觉不是同执行这件事的,Event出现得过晚,都晚过了前面所有代码
2.我上面写的listView1.ItemChecked -= listView1_ItemChecked;是我猜测的临时禁用Event的代码,不知道对不对?
我在ItemChecked里面加了两秒Sleep,Item.Add下面的代码就在那里等了两秒
完全按顺序执行的
add begin
item checked: False
item checked: True
add end-= 确实是取消掉 evenhandler
先取消掉,然后再加回去,也是没问题的Debug.WriteLine("add begin");
listView1.ItemChecked -= listView1_ItemChecked;
ListViewItem it = new ListViewItem();
it.Text = "abc";
it.Checked = true;
listView1.Items.Add(it);
listView1.ItemChecked += listView1_ItemChecked;
Debug.WriteLine("add end");
我是调试时得出的结论
listView1.ItemChecked += listView1_ItemChecked; 都执行了,ItemChecked都还没执行到
有什么问题么?
private void button1_Click(object sender, EventArgs e)
{
// 造数据
List<MyInfo> Info = new List<MyInfo>();
for (int i = 0; i < 10; i++)
{
MyInfo myInfo = new MyInfo() { Checked=true, name="Item_" + i };
Info.Add(myInfo);
} Debug.WriteLine("add begin:" + DateTime.Now.ToString("HH:mm:ss.fff"));
listView1.ItemChecked -= listView1_ItemChecked;
listView1.BeginUpdate();
listView1.Items.Clear();
Debug.WriteLine("clear end:" + DateTime.Now.ToString("HH:mm:ss.fff")); for (int i = 0; i < Info.Count; i++)
{
ListViewItem it = new ListViewItem();
it.Checked = Info[i].Checked;
it.Text = Info[i].name;
listView1.Items.Add(it);
}
listView1.EndUpdate();
listView1.ItemChecked += listView1_ItemChecked;
Debug.WriteLine("add end:" + DateTime.Now.ToString("HH:mm:ss.fff"));
}private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
// 故意延长ItemChecked事件的时间
Thread.Sleep(1000);
Debug.WriteLine("ItemChecked : " + e.Item.Checked + "-->" + DateTime.Now.ToString("HH:mm:ss.fff"));
}
输出的Log:
add begin:16:44:27.775
clear end:16:44:27.806
add end:16:44:27.806一瞬间就结束了,顺序也没问题
如果,把 -= +=那两行注掉,ItemChecked事件触发
add end直到所有的ItemChecked处理完才执行
add begin:16:46:39.074
clear end:16:46:39.091
ItemChecked : False-->16:46:40.107
ItemChecked : True-->16:46:41.078
ItemChecked : False-->16:46:42.093
ItemChecked : True-->16:46:43.099
ItemChecked : False-->16:46:44.140
ItemChecked : True-->16:46:45.142
ItemChecked : False-->16:46:46.130
ItemChecked : True-->16:46:47.142
ItemChecked : False-->16:46:48.144
ItemChecked : True-->16:46:49.174
ItemChecked : False-->16:46:50.174
ItemChecked : True-->16:46:51.160
ItemChecked : False-->16:46:52.179
ItemChecked : True-->16:46:53.181
ItemChecked : False-->16:46:54.195
ItemChecked : True-->16:46:55.211
ItemChecked : False-->16:46:56.242
ItemChecked : True-->16:46:57.273
ItemChecked : False-->16:46:58.244
ItemChecked : True-->16:46:59.246
add end:16:46:59.255
有什么问题么?
private void button1_Click(object sender, EventArgs e)
{
// 造数据
List<MyInfo> Info = new List<MyInfo>();
for (int i = 0; i < 10; i++)
{
MyInfo myInfo = new MyInfo() { Checked=true, name="Item_" + i };
Info.Add(myInfo);
} Debug.WriteLine("add begin:" + DateTime.Now.ToString("HH:mm:ss.fff"));
listView1.ItemChecked -= listView1_ItemChecked;
listView1.BeginUpdate();
listView1.Items.Clear();
Debug.WriteLine("clear end:" + DateTime.Now.ToString("HH:mm:ss.fff")); for (int i = 0; i < Info.Count; i++)
{
ListViewItem it = new ListViewItem();
it.Checked = Info[i].Checked;
it.Text = Info[i].name;
listView1.Items.Add(it);
}
listView1.EndUpdate();
listView1.ItemChecked += listView1_ItemChecked;
Debug.WriteLine("add end:" + DateTime.Now.ToString("HH:mm:ss.fff"));
}private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
// 故意延长ItemChecked事件的时间
Thread.Sleep(1000);
Debug.WriteLine("ItemChecked : " + e.Item.Checked + "-->" + DateTime.Now.ToString("HH:mm:ss.fff"));
}
输出的Log:
add begin:16:44:27.775
clear end:16:44:27.806
add end:16:44:27.806一瞬间就结束了,顺序也没问题
如果,把 -= +=那两行注掉,ItemChecked事件触发
add end直到所有的ItemChecked处理完才执行
add begin:16:46:39.074
clear end:16:46:39.091
ItemChecked : False-->16:46:40.107
ItemChecked : True-->16:46:41.078
ItemChecked : False-->16:46:42.093
ItemChecked : True-->16:46:43.099
ItemChecked : False-->16:46:44.140
ItemChecked : True-->16:46:45.142
ItemChecked : False-->16:46:46.130
ItemChecked : True-->16:46:47.142
ItemChecked : False-->16:46:48.144
ItemChecked : True-->16:46:49.174
ItemChecked : False-->16:46:50.174
ItemChecked : True-->16:46:51.160
ItemChecked : False-->16:46:52.179
ItemChecked : True-->16:46:53.181
ItemChecked : False-->16:46:54.195
ItemChecked : True-->16:46:55.211
ItemChecked : False-->16:46:56.242
ItemChecked : True-->16:46:57.273
ItemChecked : False-->16:46:58.244
ItemChecked : True-->16:46:59.246
add end:16:46:59.255嗯,你的看上去是没问题,看我的结果,我把你的代码放到我的程序里的结果,明显和你的不一样啊:
不过,我的填充数据的地方和你不一样,不是click,而是tab页切换tab1_Selected里做的,按理应该差不多呀
麻烦再帮我想想是啥原因?
add begin:10:05:19.617
clear end:10:05:19.743
add end:10:05:19.758
ItemChecked : False-->10:05:20.810
ItemChecked : True-->10:05:21.812
ItemChecked : False-->10:05:22.815
ItemChecked : True-->10:05:23.817
ItemChecked : False-->10:05:24.819
ItemChecked : True-->10:05:25.871
ItemChecked : False-->10:05:26.873
ItemChecked : True-->10:05:27.875
ItemChecked : False-->10:05:28.876
ItemChecked : True-->10:05:29.879
ItemChecked : False-->10:05:30.880
ItemChecked : True-->10:05:31.882
ItemChecked : False-->10:05:32.884
ItemChecked : True-->10:05:33.886
ItemChecked : False-->10:05:34.887
ItemChecked : True-->10:05:35.890
ItemChecked : False-->10:05:36.892
ItemChecked : True-->10:05:37.894
ItemChecked : False-->10:05:38.896
ItemChecked : True-->10:05:39.901
我放在tabcontrol的selected事件里面,也是好的啊
add end完了,才设置 Visible= true的?
这样的话,ItemChecked会在add end之后出现,也就是Visible=true那句话的时候触发
绝对是标准控件,不过我把工程集改成.net2.0了,不知道这会影响不?
我开个新工程也再试试,看能不能找到原因
不是,它是一直显示着的,此listview是tab页中的
不过你这么说的话,我是在tab的selected里面做,也就是切过来的时候,不知道那时候listview算是显示的不?
Debug.WriteLine("ItemChecked : " + e.Item.Checked + "-->" + DateTime.Now.ToString("HH:mm:ss.fff"));
就没了,为啥这么问:)
最开始: -=
中间做你自己的操作: Items.add
函数最后: +=按这个顺序执行,没有 ItemChecked:xxxxxxxxxxxx 的Log出来,不就达到目的了么
我的修改方式并没有改代码,只是把tab从palne里移出来而已,这样就好了,奇怪吧?
tabControl1_Selected
add begin:15:42:14.876
clear end:15:42:14.878
add end:15:42:14.881
ItemChecked : False-->15:42:14.990
ItemChecked : True-->15:42:15.092
ItemChecked : False-->15:42:15.194
ItemChecked : True-->15:42:15.296
tabControl1_SelectedIndexChanged
add begin:15:42:15.302
clear end:15:42:15.303
ItemChecked : False-->15:42:15.405
ItemChecked : True-->15:42:15.507
ItemChecked : False-->15:42:15.608
ItemChecked : True-->15:42:15.709
add end:15:42:15.710终于搞明白了,看上面的数据
如果在tab的selected事件里做,就变成异步的了,如果在SelectedIndexChanged事件里做,就变成同步的了,
只能说这是ms框架的设计了,好奇怪………………