0

使用 Visual Studio 2008、.Net 3.5

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

代码的想法:

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.      
}  

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

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

4

4 回答 4

2

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

此外:

  1. 如果使用ListView.Items.Clear(),则不会丢失列,因此每次都必须重新添加它们(这会激怒已调整列标题大小的用户)。
  2. 不要做整个清除和刷新的事情。将 eachListViewItemName属性设置为主键,然后就可以了ListViewItem liToRemove = listView[name];
于 2010-02-17T22:53:10.113 回答
0

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

于 2010-02-17T22:56:13.057 回答
0

用这个:

m_lv.BeginUpdate();

// 添加项目

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

不要调用“无效”,使用开始/结束更新应该可以防止闪烁和刷新......

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

希望这会有所帮助,最好的问候,汤姆。

于 2010-02-17T23:11:56.153 回答
0

它最终变得非常容易:

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

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

于 2011-10-05T18:54:44.740 回答