Home > Enterprise >  How to extract selected item from Listbox as an object
How to extract selected item from Listbox as an object

Time:06-05

How to extract a selected item from Listbox as an object. Currently, I'm taking all records from DB and I add them to the Listbox in the following way:

                var allEmployees = GetAll();
                foreach (var emp in allEmployees)
                {
                    var empFull = $"{emp.Id} - {emp.Name} {emp.Surname} - {emp.Email}";
                    listBoxViewEmp.Items.Add(empFull);
                }

However, I find it challenging to make the listBoxViewEmp.SelectedItem to object since I'm taking the entire string that contains id, name, surname, and email.

private void btnUpdate_Click(object sender, EventArgs e)
{
    if(listBoxViewEmp.SelectedItem != null)
    {
        var newForm = new UpdateForm(listBoxViewEmp.SelectedItem);
        newForm.Show();
    }
    else
    {
        MessageBox.Show("Please select employee first");
    }

}

What is the best way to handle this kind of issue?

Update: Here is my attempt, but I got only objects now in the listbox

                var allEmployees = GetAll();
                foreach (var emp in allEmployees)
                {
                    var empFull = (Employee)emp;
                    listBoxViewEmp.Items.Add(empFull);
                }

enter image description here

CodePudding user response:

The string that appears for any object added as an item to a ListBox control will be the return value of the ToString method of that object. In your case, you added a string directly to the list. So there's (likely) no way to recover the original object from the formatted string you created for that object.

Instead, override ToString for your Employee object (if appropriate to do so).


Alternatively, you can create a wrapper class whose job it is to remember the original object and to provide a custom ToString implementation for the remembered object. Such a generic formatter class might look like:

public class Formatter<T>
{
    public Formatter(T obj, Func<T, string> fnFormat)
    {
        this.obj = obj;
        this.fnFormat = fnFormat;
    }
    public T obj;
    public Func<T, string> fnFormat;
    public override string ToString() => fnFormat(obj);
}

Then, when you add items to the list box, add a Formatter wrapping that item instead. Its ToString method will be called, which will call the custom formatter for that item.

foreach (var employee in employees)
{
    this.listBox1.Items.Add(new Formatter<Employee>(employee,
        emp => $"{emp.Id} - {emp.Name} {emp.Surname} - {emp.Email}"));
}

And to access the original Employee, case the SelectedItem back to the Formatter<Employee> and access its remembered object field obj. Now you have the original Employee object back (or DB record or entity or whatever it was originally.) Example usage:

private void button1_Click(object sender, EventArgs e)
{
    Employee employee = (this.listBox1.SelectedItem as Formatter<Employee>)?.obj;
    this.label1.Text = employee?.Id.ToString();
}

CodePudding user response:

You can use databinding for this. Make a new readonly property which will return computed string you want. Than ListBox has some properties you can use:

  • Datasource - source of data which will be displayed. You can set here just simple List<Employee>.
  • DisplayMember - you set the name of the property, which value you want to see in the ListBox.
  • ValueMember - you set the name of the property which value you want to get for selected item using ListBox's SelectedValue property.

So you can do it this way:

// You should set these two properties in form's designer.
listBoxViewEmp.DisplayMember = "Info"; // "Info" is that new readonly property.
listBoxViewEmp.ValueMember = "Id";

var allEmployees = GetAll().ToList();
listBoxViewEmp.DataSource = allEmployees;

That's it. Now:

  • You will see in the listbox what you want to see there.
  • listBox.SelectedItem returns whole your Eployee object.
  • listBox.SelectedValue returns the Id value of selected employee.
  •  Tags:  
  • c#
  • Related