Store hidden value (id) in ListView
Asked Answered
R

1

6

I have a ListView where I show a list of objects (persons) with their relevant properties, which are: name (string), age (int). But this objects have also an id property, that is used to differentiate them from each other.

The question is, what is the 'correct' way to store the id value, to retrieve it when I click on the item that represents the object?

To do this I am using a hidden column (column width = 0) but I think that it isn't a good way.

foreach (var person in col.listPersons )
{
    ListViewItem lIt = new ListViewItem(person.id); //Column with width = 0
    lIt.SubItems.Add(person.name);
    lIt.SubItems.Add(person.age);
    lPer.Items.Add(lIt) //Add the item to ListView
}
Room answered 11/6, 2016 at 22:37 Comment(1)
The "correct way" would be to use a DataGridView so that everything isnt converted to string (or boxed as Object using the Tag), Dates will stay dates, ints will remain ints and so forthRetention
H
8

A simple way of adding extra data attributes is to use the Tag property. You can assign a class object with multiple properties or a simple scalar value such as your id. Tag is quite versatile and is a common property on many controls.

Our person definition.

public class Person
{
    public long id { get; set; }
    public string name { get; set; }
    public int age { get; set; }
}

Example 1: Assign the id to the ListViewItem Tag property.

foreach (var person in col.listPersons)
{
    ListViewItem lIt = new ListViewItem();
    lIt.Tag = person.id;
    lIt.SubItems.Add(person.name);
    lIt.SubItems.Add(person.age.ToString());
    lPer.Items.Add(lIt); // Add the item to ListView
}

You can then easily retrieve the id value back again:

ListViewItem lit = sender as ListViewItem;
person.id = (long)lit.Tag;

Example 2: Assign the whole person object to the ListViewItem Tag property.

foreach (var person in col.listPersons)
{
    ListViewItem lIt = new ListViewItem();
    lIt.Tag = person;
    lIt.SubItems.Add(person.name);
    lIt.SubItems.Add(person.age.ToString());
    lPer.Items.Add(lIt); // Add the item to ListView
}

Just as easily, get the person object back again:

ListViewItem lit = sender as ListViewItem;
person = (Person)lit.Tag;

Example 3: Another common way is to Use the ListViewItem.Name property. The name is treated like a Key in the ListView. You can then use this key value to pass to ListView.Items.IndexOfKey() or ListView.Items["key"] in order to search the ListView for a specific item. The Name is a string and as such isn't as flexible as the Tag, but this may be more ideal for your use case.

foreach (var person in col.listPersons)
{
    ListViewItem lIt = new ListViewItem();
    lIt.Name = person.id; // Treat the Name as a Key
    lIt.SubItems.Add(person.name);
    lIt.SubItems.Add(person.age);
    lPer.Items.Add(lIt); // Add the item to ListView

    // Retrieve the person back from the ListViewItemCollection by index.
    var personIndex = lPer.Items.IndexOfKey(person.id.ToString());
    var lItA = lPer.Items[personIndex];

    // Retrieve the person back from the ListViewItemCollection by key.
    var lItB = lPer.Items[person.id.ToString()];
}
Hamite answered 11/6, 2016 at 22:51 Comment(1)
It's exactly what I need. PD: Buen nick :)Room

© 2022 - 2024 — McMap. All rights reserved.