如何更新ListView的选定项?

7

我有一个ListView,显示多个ListViewItems行。用户可以通过单击“编辑”后打开的对话框来编辑其中一个项目。对话框关闭后,我希望修改所选的ListViewItem,以反映新的设置。

以下是我目前更新项目的方法:

private void btnEditSnmpV3Setting_Click(object sender, EventArgs e)
{
    if (lstVwSNMPv3Settings.SelectedItems.Count > 0)
    {
        ListViewItem selectedItem = lstVwSNMPv3Settings.SelectedItems[0];
        NetworkDiscoverySnmpSetting settings = (NetworkDiscoverySnmpSetting)selectedItem.Tag;
        NetworkDiscoverySnmpV3SettingsDialog dialog = new NetworkDiscoverySnmpV3SettingsDialog(settings);

        //Pass in the owner for centering of dialog.
        if (dialog.ShowDialog(this) == DialogResult.OK)
        {
            selectedItem.SubItems.Clear();
            selectedItem.Text = settings.SnmpV3Username;
            selectedItem.SubItems.Add(settings.SecurityMode.ToString());
            selectedItem.SubItems.Add(settings.AuthenticationProtocol.ToString());
            selectedItem.SubItems.Add(settings.PrivacyProtocol.ToString());
            selectedItem.Tag = settings;
        }
    }
}

我发现这是一个不好的解决方案,因为如果我的ListView的列数改变,我需要在多个地方触碰代码。
我通过在“添加”事件(而不是“编辑”)期间给NetworkDiscoverySnmpSetting提供实用方法来处理此代码重用问题:
public ListViewItem ToListViewItem()
{
    ListViewItem listViewItem = new ListViewItem();
    listViewItem.Text = SnmpV3Username;
    listViewItem.SubItems.Add(SecurityMode.ToString());
    listViewItem.SubItems.Add(AuthenticationProtocol.ToString());
    listViewItem.SubItems.Add(PrivacyProtocol.ToString());
    listViewItem.Tag = this;
    return listViewItem;
}

这是一个示例用法:

private void btnAddSnmpV3Setting_Click(object sender, EventArgs e)
{
    NetworkDiscoverySnmpSetting settings = new NetworkDiscoverySnmpSetting(NetworkDiscovery.ID);
    NetworkDiscoverySnmpV3SettingsDialog dialog = new NetworkDiscoverySnmpV3SettingsDialog(settings);
    //Pass in the owner for centering of dialog.
    if (dialog.ShowDialog(this) == DialogResult.OK)
        lstVwSNMPv3Settings.Items.Add(settings.ToListViewItem());
}

很不幸,ListView.SelectedItems不允许集合修改。因此,以下代码无法编译:

lstVwSNMPv3Settings.SelectedItems[0] = settings.ToListViewItem();

当ListView的列发生变化时,我应该如何修改我的第一个代码片段,以便在不同地方更新代码?


1
给自己一个巨大的恩惠,去谷歌并学习ObjectListView。用一个词来形容它,那就是“棒极了”。 - banging
3个回答

9

您可以修改元素本身而不是用其他的替换它,因为ListViewItem是一个类,所以它是一个引用类型。

要做到这一点,请按照以下步骤进行操作:

  • get currently selected item and save it to variable like this: ListViewItem selectedItem = lstVwSNMPv3Settings.SelectedItems[0];
  • modify your ToListViewItem method to void ToListViewItem(ListViewItem listViewItem) (return void and take ListViewItem object as parameter and modify it instead of creating a new object. It should also rather modify properties of existing subitems than creating new ones. It can look more or less like this:

    public void ToListViewItem(ListViewItem listViewItem)
    {
        listViewItem.Text = SnmpV3Username;
        listViewItem.SubItems[0].Text = SecurityMode.ToString();
        listViewItem.SubItems[1].Text = AuthenticationProtocol.ToString();
        listViewItem.SubItems[2].Text = PrivacyProtocol.ToString();
        listViewItem.Tag = this;
    }
    
  • call ToListViewItem(selectedItem);

  • you don't have to assign the modified item back to the collection, because you use a reference, which means you've just modify the same object that's in the ListView
我进行了一个快速测试,这个方法似乎能够在不产生问题的情况下修改现有条目的文本内容。

1
我将你的方法修改回到基本上与我的原始方法相同,但使用了你的想法。供以后参考 -- 设置ListViewItem的Text属性会导致向SubItems数组添加一个元素。这就是我调用Clear的原因。 :) - Sean Anderson

2

ListViewItem拥有一个bool Selected属性,您可以切换它以使其被选中或未选中。


0
一个更简单的解决方案,适用于我:
lstVwSNMPv3Settings.Items[lstVwSNMPv3Settings.SelectedIndices[0]] = myNewItem;

但是请注意首先确保已选择一个项目:

if (lstVwSNMPv3Settings.SelectedIndices.Count > 0) { ... }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接