I have a ListView which displays multiple rows of ListViewItems. The user is able to edit one of these items through a dialog which opens after clicking 'Edit.' When the dialog closes I would like to modify the selected ListViewItem such that it reflects the new settings.
Here is how I currently update my item:
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;
}
}
}
I found this to be a poor solution due to the fact that I need to touch code in multiple places if my ListView's number of columns changes.
I handled this code-reuse issue during the 'Add' event (as opposed to 'Edit') by giving NetworkDiscoverySnmpSetting
a utility method:
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;
}
which is used like so:
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());
}
Unfortunately, ListView.SelectedItems does not allow collection-modification. As such, this does not compile:
lstVwSNMPv3Settings.SelectedItems[0] = settings.ToListViewItem();
How should I change my first code-snippet so that I do not need to update my code in multiple places when ListView's columns change?
A much simpler solution, that worked for me:
But be careful to first make sure there is an item selected:
ListViewItem
s have abool Selected
property that you can toggle to make them selected or not selected.You can modify the element itself rather than replacing it with another one, because ListViewItem is a class, so it's a reference type.
In order to do this follow these steps:
ListViewItem selectedItem = lstVwSNMPv3Settings.SelectedItems[0];
modify your
ToListViewItem
method tovoid ToListViewItem(ListViewItem listViewItem)
(return void and takeListViewItem
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:call
ToListViewItem(selectedItem);
ListView
I did a quick test and the method seems to modify texts of existing items without issues.