winforms 取消选中/选中ListViewItem

dm7nw8vv  于 2023-11-21  发布在  其他
关注(0)|答案(2)|浏览(129)

我有一个包含许多项的ListViewItem,默认情况下所有的项都被选中。
我想写一个函数,它将获得需要检查的项目列表。

  1. public void NewCheckSecurities(SecurityList oSecurities)
  2. {
  3. // error checking
  4. if (oSecurities == null || oSecurities.Count == 0)
  5. {
  6. return;
  7. }
  8. // check sent securities
  9. ListView.ListViewItemCollection oItems = m_lsvSecurities.Items;
  10. if (oItems != null)
  11. {
  12. int i = 1;
  13. foreach (ListViewItem oItem in oItems)
  14. {
  15. bool bFind = oSecurities.FindSecurity((oItem.Tag as SecurityItem).Security.Symbol) != null;
  16. if(bFind)
  17. {
  18. oItem.Checked = true;
  19. }
  20. else
  21. {
  22. oItem.Checked = false;
  23. }
  24. }
  25. }
  26. }

字符串
o证券有5种证券,我想检查。
o项目大小- 2800个项目
为了检查这个问题,我不得不把这个函数拆成2个部分(find,checked)。
第一部分是一个循环,它遍历所有项,并仅使bFind为true或false。
当我把第二部分加上

  1. if(bFind)
  2. {
  3. oItem.Checked = true;
  4. }
  5. else
  6. {
  7. oItem.Checked = false;
  8. }


但是它工作太慢了。
当代码在做oItem的时候。在oItems中为每个oItem选中true或false是花了很长时间的。
有什么方法可以更快地完成吗?

mctunoxg

mctunoxg1#

该问题很可能是由组件在每次更新后重新绘制自身引起的。
这通常可以通过在您进行更改时告诉Form暂停视觉更新来加速,如下所示:

  1. this.SuspendLayout();
  2. // Do your updates here
  3. this.ResumeLayout();

字符串
它应该在this等于Form的地方运行。或者如果你更喜欢在其他地方运行它,那么你需要将Form作为参数传递给那个方法,并在那里调用Suspend...+Resume...。

chhkpiq4

chhkpiq42#

对于像ListViewDataGridView这样承载大量项目的控件,提高性能的一种方法是使用VirtualMode=true将底层列表项目的更改与UI绘制解耦。由此推论,如果您想要编写一个函数来获取需要检查的项目列表,则根本不需要接触UI,并且应该很快。

  1. public partial class MainForm : Form
  2. {
  3. public MainForm() => InitializeComponent();
  4. protected override void OnLoad(EventArgs e)
  5. {
  6. base.OnLoad(e);
  7. for (int i = 1; i <= 3000; i++)
  8. {
  9. SecuritiesList.Add(new Security { Text = $"Security {i}", IsChecked = false });
  10. }
  11. m_lsvSecurities.View = View.Details;
  12. m_lsvSecurities.HeaderStyle = ColumnHeaderStyle.None;
  13. m_lsvSecurities.Columns.Add("", 80);
  14. m_lsvSecurities.Columns.Add("Security", 300);
  15. m_lsvSecurities.CheckBoxes = true;
  16. m_lsvSecurities.VirtualMode = true;
  17. m_lsvSecurities.RetrieveVirtualItem += (sender, e) =>
  18. {
  19. if (e.ItemIndex >= 0 && e.ItemIndex < SecuritiesList.Count)
  20. {
  21. var security = SecuritiesList[e.ItemIndex];
  22. ListViewItem item = new ListViewItem(text: security.IsChecked ? "\u2612" : "\u2610");
  23. item.SubItems.Add(security.Text);
  24. e.Item = item;
  25. }
  26. else
  27. {
  28. e.Item = new ListViewItem();
  29. }
  30. };
  31. m_lsvSecurities.MouseClick += (sender, e) =>
  32. {
  33. var hti = m_lsvSecurities.HitTest(e.Location);
  34. if (hti.Location == ListViewHitTestLocations.Label)
  35. {
  36. var security = SecuritiesList[hti.Item.Index];
  37. security.IsChecked = !security.IsChecked;
  38. m_lsvSecurities.Invalidate(hti.Item.Bounds);
  39. }
  40. };
  41. m_lsvSecurities.VirtualListSize = SecuritiesList.Count;
  42. _ = benchmark();
  43. }
  44. private List<Security> SecuritiesList { get; } = new List<Security>();
  45. }

字符串
生成3000个证券的列表并显示该列表后,2秒后调用benchmark()方法来测量获取需要检查的项目列表所需的时间,在本例中是“每四个项目”。


的数据

  1. /// <summary>
  2. /// Show the dialog, wait 2 seconds, then
  3. /// run conditional set check for 3000 items.
  4. /// </summary>
  5. async Task benchmark()
  6. {
  7. await Task.Delay(TimeSpan.FromSeconds(2));
  8. Text = DateTime.Now.ToString(@"hh\:mm\:ss\.ffff tt");
  9. screenshot("screenshot.1.png");
  10. var stopwatch = Stopwatch.StartNew();
  11. // Example of a function that will get list
  12. // of items that need to be checked.
  13. setListOfItemsConditionalChecked();
  14. m_lsvSecurities.Refresh();
  15. stopwatch.Stop();
  16. Text = DateTime.Now.ToString(@"hh\:mm\:ss\.ffff tt");
  17. await Task.Delay(TimeSpan.FromSeconds(0.5));
  18. MessageBox.Show($"{stopwatch.ElapsedMilliseconds} ms");
  19. }
  20. private void setListOfItemsConditionalChecked()
  21. {
  22. for (int i = 0; i < SecuritiesList.Count; i++)
  23. {
  24. var mod = i + 1;
  25. SecuritiesList[i].IsChecked = (mod % 4 == 0);
  26. }
  27. }

列表项类

  1. {
  2. public string Text { get; set; }
  3. public bool IsChecked { get; set; }
  4. }

展开查看全部

相关问题