5

我有一个显示多行 ListViewItems 的 ListView。用户可以通过单击“编辑”后打开的对话框来编辑其中一项。当对话框关闭时,我想修改选定的 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 的列更改时不需要在多个位置更新我的代码?

4

3 回答 3

7

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

为此,请按照下列步骤操作:

  • 获取当前选定的项目并将其保存到变量中,如下所示:ListViewItem selectedItem = lstVwSNMPv3Settings.SelectedItems[0];
  • 将您的ToListViewItem方法修改为void ToListViewItem(ListViewItem listViewItem)(返回 void 并将ListViewItem对象作为参数并修改它而不是创建新对象。它还应该修改现有子项的属性而不是创建新子项。它看起来或多或少像这样:

    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;
    }
    
  • 称呼ToListViewItem(selectedItem);

  • 您不必将修改后的项目分配回集合,因为您使用引用,这意味着您只需修改ListView

我做了一个快速测试,该方法似乎可以毫无问题地修改现有项目的文本。

于 2012-06-01T19:56:21.667 回答
2

ListViewItems have a bool Selected property that you can toggle to make them selected or not selected.

于 2012-06-01T19:15:43.420 回答
0

一个更简单的解决方案,对我有用:

lstVwSNMPv3Settings.Items[lstVwSNMPv3Settings.SelectedIndices[0]] = myNewItem;

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

if (lstVwSNMPv3Settings.SelectedIndices.Count > 0) { ... }
于 2020-04-05T21:33:26.293 回答