3 Replies - 1952 Views - Last Post: 30 April 2010 - 03:38 PM Rate Topic: -----

#1 nsanf0rd  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 02-April 10

SelectedIndexChanged / delete issue

Posted 29 April 2010 - 06:25 AM

Hello,

I'm working on an address book program that holds 20 entries using an array of a user-made Class. It adds new entries taken from data in 6 text boxes, displays the last and first names in a list box, and is supposed to delete entries as well. I had this all working until I coded the SelectedIndexChanged event handler for the list box, as the user needs to be able to select a name in the box and have the information be displayed in the text boxes. That part of it works fine, but now when I attempt to delete an entry I get an error: Object reference not set to an instance of an object. I understand what the error is telling me, but I'm not sure how to fix it.

Code for the list box:

 private void lbNames_SelectedIndexChanged(object sender, EventArgs e)
        {
            fullName = lbNames.SelectedItem.ToString();

            int commaPosition = fullName.IndexOf(',');
            string LastName = fullName.Substring(0, commaPosition);
            string FirstName = fullName.Substring(commaPosition + 2);

            int i;
            for (i = 0; i < HIGH; i++)
            {
                if (AddressBook[i].LName == LastName)
                {
                    break;
                }
            }
            
            
                if (i < HIGH)
                {
                    txtFirstName.Text = AddressBook[i].FName;
                    txtLastName.Text = AddressBook[i].LName;
                    txtStreetAddress.Text = AddressBook[i].AName;
                    txtCity.Text = AddressBook[i].CName;
                    txtState.Text = AddressBook[i].SName;
                    mtxtZipCode.Text = AddressBook[i].ZName;

                }
                else
                {
                    MessageBox.Show("Name not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            

        }



I get the error at the first line of that code.


Code for the delete button, which worked prior to coding the list box:

 private void btnDelete_Click(object sender, EventArgs e)
        {
            fullName = lbNames.SelectedItem.ToString();

            int commaPosition = fullName.IndexOf(',');
            string LastName = fullName.Substring(0, commaPosition);
            string FirstName = fullName.Substring(commaPosition + 2);

            int i;
            for (i = 0; i < HIGH; i++)
            {
                if (AddressBook[i].LName == LastName)
                {
                    break;
                }
            }
            if (i < HIGH)
            {
                //Delete selected entry from list box and array
                lbNames.Items.Remove(fullName);

                for (int j = i; j < NextEntry; j++)
                {
                    AddressBook[j] = AddressBook[j + 1];
                }
                NextEntry--;
                AddressBook[NextEntry] = new MyContacts();
                

            }
            else
            {
                MessageBox.Show("Name not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }



If you need more code to answer this question, let me know and I will post it. Also, if I wanted the names that display in the list box to appear in alphabetical order by last name, do I handle that within the list box or by ordering the array? Any help on this is much appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: SelectedIndexChanged / delete issue

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4318
  • View blog
  • Posts: 12,100
  • Joined: 18-April 07

Re: SelectedIndexChanged / delete issue

Posted 29 April 2010 - 08:01 PM

Well the problem is that when you do a delete it is going to trigger your SelectIndexChanged event in the listbox. This will be ok unless the item currently selected is the one you just deleted. So what you need to do is take control of the selected item and move it to another item before you go and delete it. You can do this by detecting which item index is selected (get the value from selectedIndex) then change the selectedIndex (like add 1 to it), then delete the one that was previously selected.

The one thing you have to watch though is that when you go to move which item is selected that you first check if there are items in the listbox. You can do this by simply doing a listbox.Items.Count check against 0.


As for your sorting question, assuming you are overriding your ToString method in your class so that it displays correctly in the listbox, all you have to do is turn on the "Sorted" property for the listbox. Set that to "True" and it should sort your items for you and keep them sorted. This will work fine for simple strings and in alphabetical order. If you want to do your own custom sorting, then you have to go through a longer way of inheriting from the ListBox class and overriding its Sort method. It may also require you to build in a IComparable interface into your class as well depending on the type of sorting you want to do.

Hope this helps! :)
Was This Post Helpful? 0
  • +
  • -

#3 nsanf0rd  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 02-April 10

Re: SelectedIndexChanged / delete issue

Posted 30 April 2010 - 02:54 PM

What you are saying makes sense to me, but I'm not really sure how to go about implementing that in code. If you have a link to information on that it would be great, as everything I have looked at doesn't seem to have anything other than vague concepts.

I've made some changes to my code from what it was before, but am still dealing with a bug or two. I'm no longer getting the error that I listed previously. What is happening now is when I have multiple entries in the list box (also in the array) there is a bug when I delete an entry other than the one at the top of the list. For example, if I have 4 entries, and I delete the 4th, it is also deleting the array elements for the 3rd entry, but leaving the name in the list box. When I click on that name is when I get the error, because there is now no array data associated with that list box item. I will post my entire code so you can see what I am trying to do.


namespace _1001C_IT254_02AU_NathanSanford_Unit10_Final_project
{
    public partial class frmUnit10FinalProject : Form
    {

        //Declare variable for later display of Last Name, First Name
        string fullName;

        //Declare constant for upper bound of array
        const int HIGH = 20;
        //Declare array
        MyContacts[] AddressBook = new MyContacts[HIGH];
        //Declare counter variable for use with array
        int NextEntry = 0;


        public frmUnit10FinalProject()
        {
            
            
            InitializeComponent();
            //Set value of variable
            

            //Initialize the array
            for (int i = 0; i < HIGH; i++)
            {
                AddressBook[i] = new MyContacts();
            }
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            //Get data from the text boxes and add to the array
            if (ValidateTextBoxes() == true)
            {
                AddTextBoxDataToAddressBook();
            }
            else
            {
                MessageBox.Show("One or more textboxes contains no data.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
            //Sort the list box
            lbNames.Sorted = true;
            ResetTextBoxes();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            //Delete the selected entry from the array and the list box

            removeFromArray();

            removeFromList();

            ResetTextBoxes();

        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            //Call the method to reset text boxes
            ResetTextBoxes();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            //Close the program
            this.Close();
        }

        private void ResetTextBoxes()
        {
            //Reset the data in the textboxes
            txtCity.Clear();
            txtFirstName.Clear();
            txtLastName.Clear();
            txtState.Clear();
            txtStreetAddress.Clear();
            mtxtZipCode.Clear();
            //Reset focus to first textbox
            txtFirstName.Focus();
        }

        private bool ValidateTextBoxes()
        { 
            //Validate the user-entered data
            //Set check to false
            bool rc = false;

            if ((txtFirstName.Text == "")
                || (txtLastName.Text == "")
                || (txtStreetAddress.Text == "")
                || (txtCity.Text == "")
                || (txtState.Text == "")
                || (mtxtZipCode.Text == ""))
            {
                rc = false;
            }
            else
                rc = true;

            return rc;            

        }

        private void AddTextBoxDataToAddressBook()
        {
            try
            {
                //Set the text box data to the array values and add to the array
                AddressBook[NextEntry].FName = txtLastName.Text + ", " + txtFirstName.Text;                
                AddressBook[NextEntry].AName = txtStreetAddress.Text;
                AddressBook[NextEntry].CName = txtCity.Text;
                AddressBook[NextEntry].SName = txtState.Text;
                AddressBook[NextEntry].ZName = mtxtZipCode.Text;
                //Display and add names in the list box
                fullName = AddressBook[NextEntry].FName.ToString();
                lbNames.Items.Add(fullName);
                NextEntry++;
            }
            catch
            {
                MessageBox.Show("Please check input data.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void lbNames_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbNames.SelectedItem != null)
            {
                //Get the data from the array for the selected list box item
                fullName = lbNames.SelectedItem.ToString();

                int commaPosition = fullName.IndexOf(',');
                //string LastName = fullName.Substring(0, commaPosition);
                //string FirstName = fullName.Substring(commaPosition + 2);

                //Search the array for the selected entry
                int i;
                for (i = 0; i < HIGH; i++)
                {
                    if (AddressBook[i].FName == fullName)
                    {
                        break;
                    }
                }

                //Display array values for selected list box item in the text boxes
                if (i < HIGH)
                {
                    
                    txtLastName.Text = fullName.Substring(0, commaPosition);
                    txtFirstName.Text = fullName.Substring(commaPosition + 2);
                    txtStreetAddress.Text = AddressBook[i].AName;
                    txtCity.Text = AddressBook[i].CName;
                    txtState.Text = AddressBook[i].SName;
                    mtxtZipCode.Text = AddressBook[i].ZName;

                }
                else
                {
                    MessageBox.Show("Name not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            

        }        

        private void removeFromArray()
        {
            try
            {
                
                
                fullName = lbNames.SelectedItem.ToString();
                //int commaPosition = fullName.IndexOf(',');
                //string LastName = fullName.Substring(0, commaPosition);
               // string FirstName = fullName.Substring(commaPosition + 2);

                //Search array for selected entry and remove it

                for (int i = 0; i < HIGH; i++)
                {
                    if ( AddressBook[i].FName == fullName)  
                        
                    {
                        for (int j = i; j < NextEntry; j++)
                        {
                            AddressBook[j] = AddressBook[i];                            
                            
                        }
                        NextEntry--;
                        break;
                        
                    }
                }
            }
            catch
            {
                MessageBox.Show("Unexpected error while deleting entry.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private void removeFromList()
        {
            try
            {
                //Remove selected entry from the list box
                //lbNames.SelectedIndex = 0;
                lbNames.Items.Remove(fullName);
                lbNames.ClearSelected();
                
            }
            catch
            {
                MessageBox.Show("Unexpected error while deleting entry.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }



Thanks again for any help or ideas.
Was This Post Helpful? 0
  • +
  • -

#4 Nakor  Icon User is offline

  • Professional Lurker
  • member icon

Reputation: 441
  • View blog
  • Posts: 1,488
  • Joined: 28-April 09

Re: SelectedIndexChanged / delete issue

Posted 30 April 2010 - 03:38 PM

One way that might work would be to completely reset the listbox after deleting the item from the array. Create a method clears the items of the listbox (listbox.Items.Clear()) and then fills the listbox from the array. Call that method when the program loads to fill it initially and then call it when you delete an item from the array.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1