HelpNeeder
HelpNeeder

Reputation: 6480

How to prevent SelectedIndexChanged event from firing in ListBox after removing an item from it

I am working on selecting an item which will cause deletion of selected item. The problem is that when I delete an item I am selecting additional item which cause another deletion...

How do I unselest/deselect after deleting selected item?

This causes my problem:

    void lbMessage_SelectedIndexChanged(object sender, EventArgs e)
    {
        DialogResult result = new DialogResult();

        result = MessageBox.Show("Are you sure you want to remove this item?", "Removal Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Information);

        if (result == DialogResult.Yes)
        {
            lbMessage.Items.Remove(lbMessage.SelectedItem); 
            lbMessage.SelectedIndex = -1;
        }
        else
        {
        }
    }

    private void btnAddMessage_Click(object sender, EventArgs e)
    {
        lbMessage.Items.Add(txtMessage.Text);
        txtMessage.Text = string.Empty;
    }

Upvotes: 2

Views: 12679

Answers (5)

LarsTech
LarsTech

Reputation: 81610

Try removing the SelectedIndexChanged event before removing the item, then add it back in:

private void lbMessage_SelectedIndexChanged(object sender, EventArgs e) {
  if (MessageBox.Show("Are you sure you want to remove this item?", 
                      "Remove Confirmation", 
                      MessageBoxButtons.YesNo,
                      MessageBoxIcon.Question) == DialogResult.Yes) {
    lbMessage.SelectedIndexChanged -= lbMessage_SelectedIndexChanged;
    lbMessage.Items.Remove(lbMessage.SelectedItem);
    lbMessage.SelectedIndexChanged += lbMessage_SelectedIndexChanged;
  }
}

Upvotes: 11

Wizetux
Wizetux

Reputation: 756

The shear act of removing the item from the Items collection causes the items to change their index. This thus calls the "SelectedIndexChanged" event again on the list box. To prevent this, you would need to set a flag before the remove function to indicate that the SelectedIndexChange is being called after the remove and prevent the event from occuring. You can do that by the following.

    private bool afterRemove = false;
    void lbMessage_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (afterRemove)
        {
            afterRemove = false;
            return;
        }

        DialogResult result = new DialogResult();

        result = MessageBox.Show("Are you sure you want to remove this item?", "Removal Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Information);

        if (result == DialogResult.Yes)
        {
            afterRemove = true;
            lbMessage.Items.Remove(lbMessage.SelectedItem); 
            // Another call to "lbMessage_SelectedIndexChanged" is made right here.
       }
    }

    private void btnAddMessage_Click(object sender, EventArgs e)
    {
        lbMessage.Items.Add(txtMessage.Text);
        txtMessage.Text = string.Empty;
    }

An alternative that might be easier to understand could be the following.

    private bool afterRemove = false;
    void lbMessage_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (afterRemove)
            return;

        DialogResult result = new DialogResult();

        result = MessageBox.Show("Are you sure you want to remove this item?", "Removal Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Information);

        if (result == DialogResult.Yes)
        {
            afterRemove = true;
            lbMessage.Items.Remove(lbMessage.SelectedItem); 
            // Another call to "lbMessage_SelectedIndexChanged" is made right here.
            afterRemove = false;
       }
    }

Upvotes: 0

itsme86
itsme86

Reputation: 19496

What if you just either wrap your code an in if() that checks for lbMessage.SelectedIndex == -1, or write a check for it at the beginning and return if it's true:

void lbMessage_SelectedIndexChanged(object sender, EventArgs e)
{
  if(lbMessage.SelectedIndex == -1)
    return;

    DialogResult result = new DialogResult();

    result = MessageBox.Show("Are you sure you want to remove this item?", "Removal Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Information);

    if (result == DialogResult.Yes)
    {
        lbMessage.Items.Remove(lbMessage.SelectedItem); 
        lbMessage.SelectedIndex = -1;
    }
}

Upvotes: 0

Jeremy Thompson
Jeremy Thompson

Reputation: 65544

If you like it that way without a delete button then just do this:

bool isAfterDelete = false;
void lbMessage_SelectedIndexChanged(object sender, EventArgs e)
{
    if (isAfterDelete)
    {
        isAfterDelete = false;
        return;
    }
    DialogResult result = new DialogResult();

    result = MessageBox.Show("Are you sure you want to remove this item?", 
                             "Removal Confirmation", 
                             MessageBoxButtons.YesNo, 
                             MessageBoxIcon.Information);

    if (result == DialogResult.Yes)
    {
        lbMessage.Items.Remove(lbMessage.SelectedItem); 
        isAfterDelete = true;
        lbMessage.SelectedIndex = -1;
    }
    else
    {
    }
}

Upvotes: 1

Hand-E-Food
Hand-E-Food

Reputation: 12794

Setting SelectedIndex = -1 is raising the SelectedIndexChanged event. Check if there is nothing selected at the start of the event.

void lbMessage_SelectedIndexChanged(object sender, EventArgs e) 
{
    if (lbMessage.SelectedIndex == -1) return;
    ...
}

Upvotes: 4

Related Questions