C# ListView 删除项目后的项目选择问题

Posted

技术标签:

【中文标题】C# ListView 删除项目后的项目选择问题【英文标题】:C# ListView item selection problem after deleting an item 【发布时间】:2011-01-18 02:34:57 【问题描述】:

使用 Visual Studio 2008、.Net 3.5

我有一个 ListView 加载了一堆项目。我有一个用于删除项目的右键单击弹出窗口。删除一个项目后,我通过重新访问我的主要数据重新绘制列表视图,并重置所选项目。但是,所选项目不会显示为已选择

代码思路:

public ListView m_lv;  
public MyDataCollection m_Data;  // Has a function to get data based on a tag.  

public void RemoveEventHandler(object sender, EventArgs e)  
  
  int iSelectedItem= m_lv.FocusedItem.Index;

  int iDataIndexToRemove= m_Data.GetIndexOf(m_lv.FocusedItem.Tag.ToString());  

  m_Data.RemoveAt(iDataIndexToRemove);  // Remove the item.  

  if(0 != m_lv.Items.Count)  
    
    if(iSelectedItem == m_Data.Items.Count)  // Removed last.  
      iSelectedItem= m_Data.Items.Count - 1;  
  

  m_lv.Items.Clear();  // Clear the list view items.  

  // Completely rebuild the list view.  
  foreach(MyData md in m_Data)  
    
    ListViewItem lvi= new ListViewItem(md.Column0.ToString());  
    lvi.SubItems.Add(md.Column1.ToString());  
    lvi.SubItems.Add(md.Column3.ToString());  
    lvi.SubItems.Add(md.Column4.ToString());  

    m_lv.Items.Add(lvi);  
    

  // Set up tags, column sizes, etc.  

  if(0 != m_lv.Items.Count)  
    m_lv.Items[iSelectedItem].Selected= true;  // Set the selection.      
  

如果我执行上述操作,除非我重新调整列的大小或排序,否则所选项目永远不会显示为已选择的视觉(没有背景颜色更改)。然后它显示为选中。但是,如果我使用调试器或添加按钮以使用消息框向我显示所选项目,则项目知道它已被选中。

我知道这是某种刷新/绘图问题 - 有什么想法吗?

【问题讨论】:

【参考方案1】:

听起来您的 ListView 由于右键单击弹出窗口而没有焦点,并且将 HideSelection 设置为 true。这意味着当您的项目选中时,WinForms 不会显示它。首先关闭HideSelection 进行检查,然后您需要一些代码将焦点设置回列表视图。

另外:

    如果您使用ListView.Items.Clear(),您不会丢失列,因此每次都必须重新添加它们(这会激怒已调整列标题大小的用户)。 不要做整个清除和刷新的事情。将每个ListViewItemName 属性设置为主键,然后你可以做ListViewItem liToRemove = listView[name];

【讨论】:

你是对的——“HideSelection”属性设置为“false”。这似乎是一个焦点问题。注意我正在使用 ListView.Items.Clear() 以便我只清除项目,而不是列。我不确定您对 ListViewItem Name 属性有何看法。我认为您的意思是从视图中删除该项目,并从数据集合中删除相应的数据。我最初是这样做的,但遇到了刷新问题,并决定重新绘制整个项目。感谢他的帮助!【参考方案2】:

设置选择后,尝试在 ListView 上调用 Invalidate 方法。

【讨论】:

【参考方案3】:

使用这个:

m_lv.BeginUpdate(); // 添加项目 m_lv.EndUpdate(); // if(0 != m_lv.Items.Count) m_lv.Items[iSelectedItem].Selected= true; // 设置选择。

不要调用“无效”,使用 Begin/End Update 应该可以防止闪烁和刷新...

编辑:解释我在声明背后的推理...... BeginUpdate 冻结所有 WM_PAINT 消息...EndUpdate 解冻 WM_PAINT,这使得向列表中添加项目看起来更快,而且无论如何,在调用 EndUpdate 之后,它会刷新!选择可以是任何一种方式,我更喜欢将它放在 EndUpdate 之外...这是我的意见...Invalidate 生成 WM_PAINT 消息,但不一定立即处理...不建议在其中调用 Invalidate()由于刷新会减慢添加项目的循环!

希望这会有所帮助, 最好的祝福, 汤姆。

【讨论】:

无效有什么问题? Begin/EndUpdate 如何帮助解决刷新问题?那么 EndUpdate 不应该在设置选择之后吗?【参考方案4】:

结果很简单:

// Figure out index of item to remove, iRemoved, do some work....  

m_lv.Items.RemoveAt(iRemoved);  
m_lv.Refresh();

// Figure out what is left so new selection, iNewSelection, can be set....
m_lv.Items[iNewSelection].Selected = true;  

忘了我还没有更新这篇文章!

【讨论】:

以上是关于C# ListView 删除项目后的项目选择问题的主要内容,如果未能解决你的问题,请参考以下文章

从listView中删除项目仅删除最后一项未选择的元素android

使用自定义arrayadapter从listview android中删除复选框选择的多个项目

ListView 项目的删除选项始终删除第一个项目,无论单击哪个项目

Xamarin MVVM 从另一个页面删除 Listview 项目

基于布尔值的 ListView 项目可见性

使用按钮删除 Listview w/ArrayAdapter 中的选定项目