Search code examples
c#listboxstring-formatting

How to save a selected item (that has string formatting) into multiple textboxes


I am currently working on a system that saves items as tasks to do, one of the features is to edit one of these tasks. each item in the listbox is formatted and added like this:

listFormat = "{0, -10} {1,-35} {2, -20} {3, -20} {4, -20} {5, -15} {6, -10}";
lstMain.Items.Add(string.Format(listFormat, sName, sSpec, sType, sProgress, sContact, sStart, sEnd));

In order for me to edit each one individually, I need to put each variable that was added into a separate textbox but the whole line is one item so I don't know what to do in order to be able to edit them.

Note: once I can get each part of the item in the list box into several text boxes I will be able to add them back which is no problem, I just need to get them there. Thanks alot.


Solution

  • You might consider creating a Task class that has properties for each of those items, and possibly an override of ToString that outputs your string. Then you can have a BindingList of those and then bind the Listbox to it.

    This way you can easily edit and update your ListBox.

    Here's a copy/paste-able sample that should help. The Task class is at the bottom:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        // This will hold the items displayed in the ListBox
        private BindingList<Task> taskList;
    
        // Manually creating the controls here so you can copy/paste
        private ListBox taskListBox;
        private Button btnEdit;
    
        private void Form1_Load(object sender, EventArgs e)
        {
            // Create a few "Tasks" and add them to our BindingList
            taskList = new BindingList<Task>
            {
                new Task("john", "jSpec", "jType", "jProg",
                    "jContact", "jStart", "jEnd"),
                new Task("mary", "mSpec", "mType", "mProg",
                    "mContact", "mStart", "mEnd"),
                new Task("luther", "lSpec", "lType", "lProg",
                    "lContact", "lStart", "lEnd"),
            };
    
            // Create the ListBox
            taskListBox = new ListBox
            {
                Width = Width - 50,
                Left = 10,
                Top = 30,
                DataSource = taskList
            };
    
            Controls.Add(taskListBox);
    
            // Create the Button
            btnEdit = new Button
            {
                Text = "Edit Task",
                Width = 100,
                Left = taskListBox.Left + taskListBox.Width - 100,
                Top = taskListBox.Top + taskListBox.Height + 10
            };
            btnEdit.Click += BtnEdit_Click;
    
            Controls.Add(btnEdit);
        }
    
        // When you select an item in the list box and click the button,
        // the selected item will be automatically updated. You can modify
        // this code to get the actual values from the user for whatever 
        // properties you want the user to be able to update
        private void BtnEdit_Click(object sender, EventArgs e)
        {
            // Pretend we get a value from the user
            var newName = "New Name";
            var newEnd = "New End";
    
            // Get the selected task
            var selectedTask = taskList[taskListBox.SelectedIndex];
    
            // Change some of it's property values
            selectedTask.Name = newName;
            selectedTask.End = newEnd;
    
            // Update the data in the listbox and notify the user
            taskList.ResetBindings();
            MessageBox.Show("Updated selected item");
        }
    }
    
    // The Task class, with properties to represent the values from your code sample
    public class Task
    {
        public string Name { get; set; }
        public string Spec { get; set; }
        public string Type { get; set; }
        public string Progress { get; set; }
        public string Contact { get; set; }
        public string Start { get; set; }
        public string End { get; set; }
    
        public Task(string name, string spec, string type, string progress,
            string contact, string start, string end)
        {
            Name = name; Spec = spec; Type = type; Progress = progress;
            Contact = contact; Start = start; End = end;
        }
    
        public override string ToString()
        {
            return $"{Name,-10} {Spec,-35} {Type,-20} {Progress,-20} " +
                   $"{Contact,-20} {Start,-15} {End,-10}";
        }
    }
    

    Now to answer your question about getting the items into the Textboxes - well that's pretty easy. In the selection changed event of the listbox, you can take the selected task (see the sample code in the button click event), and set each text box to one of the selected task's properties.

    Then in the button click event, we get the selected Task already, so all you have to do is set each property to the correct value from each textbox.