Search code examples
c#formsediting

Issue with editing data within a list box using multiple forms


In my program I allow the user to select a student record from the list box, when they hit the edit button a new form opens. This form displays the id and mark of the student they have selected. I am required to let the user edit that mark and update the list box. I am having trouble letting the user edit, and would appreciate any advice on this. (I am having trouble figuring out what to do when I have the user's data inside the edit form)

I'm not allowed to use LINQ, so a solution or advice on how to do it without it would be greatly appreciated.

Main form:

private void btnEditMark_Click(object sender, EventArgs e) {
    string[] s_rec_arr;

    if (lstMarks.SelectedIndex == -1) {
        MessageBox.Show("please select a student");
    } else {
        ModuleData.s_rec = lstMarks.SelectedItem.ToString();
        s_rec_arr = ModuleData.s_rec.Split(':');
        ModuleData.s_id = s_rec_arr[0];
        ModuleData.s_mark = s_rec_arr[1];
        editMark myEditRecordForm = new editMark();
        this.Hide();
        myEditRecordForm.ShowDialog();
    }
}

Edit form:

public partial class editMark : Form {
    public editMark() {
        InitializeComponent();
        StartPosition = FormStartPosition.CenterScreen;
        txtStudentID.Focus();
    }

    private void btnSubmit_Click(object sender, EventArgs e) {
    }

    private void btnClose_Click(object sender, EventArgs e) {
        this.Hide();
        Form1 myForm = new Form1();
        myForm.ShowDialog();
    }

    private void editMark_Load(object sender, EventArgs e) {
        txtStudentID.Text = ModuleData.s_id;
        txtMark.Text = ModuleData.s_mark;
    }
}

Solution

  • You can add any type of object to a list box, not just strings. Create a student class and add Student objects to the listbox. Or maybe you prefer to use your ModuleData class. But in any case, you don't need to use s_rec with a colon-separated string.

    public class Student
    {
        public string Id { get; set; }
        public string Mark { get; set; }
    
        // Required to make to have the list box display useful information about students.
        public override string ToString()
        {
            return $"Id = {Id}, Mark = {Mark}";
        }
    }
    

    Now add a parameter to the edit form's constructor to be able to pass the student

    private Student _student;
    
    public editMark(Student student)
    {
        InitializeComponent();
    
        // Remember the student
        _student = student;
    
        StartPosition = FormStartPosition.CenterScreen;
    
        txtStudentID.Text = student.Id;
        txtMark.Text = student.Mark;
        txtStudentID.Focus();
    }
    

    In the editform, if you do Form1 myForm = new Form1();, this will create a new instance of Form1 instead of of using the existing hidden one.

    Remember that a class is a reference type, therefore it is not necessary to pass the student back to the first form, because this one also has a reference to the same student. Only update its properties

    private void btnClose_Click(object sender, EventArgs e)
    {
        _student.Id = txtStudentID.Text; // Only id the Id is editable.
        _student.Mark = txtMark.Text;
    
        Close();
    }
    

    In the main form

    private void BtnEditMark_Click(object sender, EventArgs e)
    {
        if (lstMarks.SelectedIndex == -1) {
            MessageBox.Show("please select a student");
        } else {
            var student = (Student)lstMarks.SelectedItem;
    
            // Pass the student as to the edit form
            var myEditRecordForm = new editMark(student);
            Hide();
            myEditRecordForm.ShowDialog(); // The code pauses here until the edit form is closed.
            Show(); // Doing this here prevents you from having the edit form knowing about Form1.
    
            // To display the changes.
            lstMarks.Items[lstMarks.SelectedIndex] = student;
        }
    }