ListView.Items.Clear 似乎删除了群组关联
ListView.Items.Clear seems to remove group association
我偶然发现了以下问题:我正在使用 的答案在 LargeIcon 视图中创建经过筛选的项目列表。我为列表视图定义组:
// Define the Groups within the listview.
foreach (CategoryObject category in JManager.jfo.categories)
{
ListViewGroup lvg = new ListViewGroup();
lvg.Header = lvg.Name = category.name;
channellistView.Groups.Add(lvg);
}
我使用以下代码在方法中将项目迭代添加到列表视图和主列表中:
lvi.Group = channellistView.Groups[CategoryName];
lvi.Tag = Obj;
channellistView.Items.Add(lvi);
ListViewItem mlvi = lvi.Clone() as ListViewItem;
mlvi.Group = channellistView.Groups[CategoryName];
masterChannelList.Add(mlvi);
这是我在 'filter' 文本框中键入字母时处理过滤的代码:
channellistView.BeginUpdate();
channellistView.Items.Clear();
// This filters and adds your filtered items to listView
foreach (ListViewItem item in masterChannelList.Where(lvi =>
lvi.Text.ToLower().StartsWith(searchmetroTextBox.Text.ToLower().Trim())))
{
channellistView.Items.Add(item);
}
channellistView.EndUpdate();
问题发生在我输入字符串的第二个字母后。似乎该行:
channellistView.Items.Clear();
以某种方式改变了主列表中的群组集合。我知道这一点是因为我在上面的行中设置了一个断点并显示了特定项目的主列表组。执行上面的行后,项目的组设置为空。这导致列表现在显示一个“默认”分组,其中包含其组被取消的项目。
据我了解,相关行不应以任何方式修改组集合。
通过更多的调试,我能够解决这个问题。我注意到组 属性 也有一个“项目”集合,用于跟踪分配给该组的项目。在调试期间,我注意到这些项目往往会重复。这让我检查了我用来分配项目的代码。这就是我发现问题的地方。
我在将项目添加到主列表时并未创建项目的新实例。我正在使用每个项目的副本。所以,我将该代码更改为:
ListViewItem mlvi = new ListViewItem();
mlvi.Text = Obj.title;
mlvi.ImageIndex = 1;
mlvi.Group = channellistView.Groups[CategoryName];
mlvi.Tag = Obj;
masterChannelList.Add(mlvi);
此外,我需要将筛选结果的代码更改为:
// This filters and adds your filtered items to listView
foreach (ListViewItem item in masterChannelList.Where(lvi => lvi.Text.ToLower().StartsWith(searchmetroTextBox.Text.ToLower().Trim())))
{
ListViewItem filteredItem = new ListViewItem();
filteredItem.Text = item.Text;
filteredItem.Group = item.Group;
filteredItem.ImageIndex = item.ImageIndex;
channellistView.Items.Add(filteredItem);
}
新代码确保我得到列表视图项的新实例而不是副本。
我偶然发现了以下问题:我正在使用
// Define the Groups within the listview.
foreach (CategoryObject category in JManager.jfo.categories)
{
ListViewGroup lvg = new ListViewGroup();
lvg.Header = lvg.Name = category.name;
channellistView.Groups.Add(lvg);
}
我使用以下代码在方法中将项目迭代添加到列表视图和主列表中:
lvi.Group = channellistView.Groups[CategoryName];
lvi.Tag = Obj;
channellistView.Items.Add(lvi);
ListViewItem mlvi = lvi.Clone() as ListViewItem;
mlvi.Group = channellistView.Groups[CategoryName];
masterChannelList.Add(mlvi);
这是我在 'filter' 文本框中键入字母时处理过滤的代码:
channellistView.BeginUpdate();
channellistView.Items.Clear();
// This filters and adds your filtered items to listView
foreach (ListViewItem item in masterChannelList.Where(lvi =>
lvi.Text.ToLower().StartsWith(searchmetroTextBox.Text.ToLower().Trim())))
{
channellistView.Items.Add(item);
}
channellistView.EndUpdate();
问题发生在我输入字符串的第二个字母后。似乎该行:
channellistView.Items.Clear();
以某种方式改变了主列表中的群组集合。我知道这一点是因为我在上面的行中设置了一个断点并显示了特定项目的主列表组。执行上面的行后,项目的组设置为空。这导致列表现在显示一个“默认”分组,其中包含其组被取消的项目。
据我了解,相关行不应以任何方式修改组集合。
通过更多的调试,我能够解决这个问题。我注意到组 属性 也有一个“项目”集合,用于跟踪分配给该组的项目。在调试期间,我注意到这些项目往往会重复。这让我检查了我用来分配项目的代码。这就是我发现问题的地方。
我在将项目添加到主列表时并未创建项目的新实例。我正在使用每个项目的副本。所以,我将该代码更改为:
ListViewItem mlvi = new ListViewItem();
mlvi.Text = Obj.title;
mlvi.ImageIndex = 1;
mlvi.Group = channellistView.Groups[CategoryName];
mlvi.Tag = Obj;
masterChannelList.Add(mlvi);
此外,我需要将筛选结果的代码更改为:
// This filters and adds your filtered items to listView
foreach (ListViewItem item in masterChannelList.Where(lvi => lvi.Text.ToLower().StartsWith(searchmetroTextBox.Text.ToLower().Trim())))
{
ListViewItem filteredItem = new ListViewItem();
filteredItem.Text = item.Text;
filteredItem.Group = item.Group;
filteredItem.ImageIndex = item.ImageIndex;
channellistView.Items.Add(filteredItem);
}
新代码确保我得到列表视图项的新实例而不是副本。