By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,157 Members | 891 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,157 IT Pros & Developers. It's quick & easy.

SelectedIndexChanged causes selectedindex to reset to -1?

P: n/a
Hi,

I have a couple of win forms where I am editing values that are stored in a
SQL database.

I'm using the listbox control to hold the data object each form interacts
with. Each object is defined by my own classes.

On the first form, I use an approach to reduce the number of database calls.
This essentially consists of :

1. Update the values in the database
2. Update the copy of the object currently being edited with the new values
so that is matches the values saved to the db
3. Re-insert the updated object back into the listbox at the same position.

Step 3 is achieved very simply by the following code:
Me.lbCampaigns.Items.Item(Me.CurrentCampaign.ListP os) = Me.CurrentCampaign

(The ListPos is an integer property of the object class that is set when the
item is selected from the listbox.)

The re-insertion of the object to the listbox causes the
SelectedIndexChanged event to fire (although strictly speaking we have not
moved the selection index). In my case, I handle this event and make a call
to refresh the visual control values with the updated object (this is a bit
redundant as we are not moving between selected items, but I can't prevent
the event firing). The SelectedIndex remains at the original value as per
the users selection.

Ok, so this all seems to work fine.

So, I wanted to use the same process on the second form. I implemented
another class to match the requirements of this form. This class also has a
ListPos property defined to store the SelectedIndex value.

In the same manner as on the first form, I copied the updated object
instance back into the listbox.
Me.lbQModes.Items.Item(Me.CurrentQMode.ListPos) = Me.CurrentQMode

However, for some reason, as soon as the SelectedIndexChanged event begins,
the SelectedIndex value is reset to -1, which then prevents the subsequent
procedures from being able to operate properly as they rely on being able to
identify and use a selected item.

I can find no obvious or sensible reason for why this second form should
cause a different behaviour in the SelectedIndexChanged event, so I have
resorted to making a second database call in order to totally reload the
listbox control, then loop through to find the matching ID of the item
selected and re-selecting it.

This approach seems heavy-handed to me and is especially frustrating given
that it works correctly on the first form. I have checked all properties of
the two different listboxes to see if this might have been a possible cause,
but other than name, anchor, position and size, they are using identical
property settings.

I'm at a loss to explain it - can anyone perhaps indicate where I might be
missing something? Not urgent - as I say I've used a total refresh approach
to get past it, but I would prefer the more elegant solution to work!

Thanks.
Oct 3 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
First of all, you have to understand what happens when the selection in a
ListBox, (or various other controls), happens.

If you have no item selected and select an item, the SelectedIndexChanged
fires once.

If you have an item already selected and select another item, the
SelectedIndexChanged fires twice. The first time as the current item becomes
deselected and the SelectedIndex becomes -1 and the second time as the new
item becomes selected. This is easily handled by testing for SelectedIndex
= -1 or SelectedItem IsNothing in the SelectedIndexChanged event handler.

Using the ListBox, as you are, as a container for a collection of your
Campaign objects is perfectly fine but you have to remember that the that
the ListItem does not contain a Campaign object, rather it contains a
reference to your Campaign object.

Because of this there is no need to 'reinsert', as you call it, when you
update one or more properties of the Campaign object. This can easily be
confirmed by:

CurrentCampaign = CType(lbCampaigns.SelectedItem, Campaign)

CurrentCampaign.ListPos = 12345

Console.WriteLine(CType(lbCampaigns.SelectedItem,
Campaign).ListPos.ToString())

The result should be 12345 and demonstrates that CurrentCampaign and
lbCampaigns.SelectedItem both hold references to the same object without any
need to 'reinsert'.

The act of 'reinsert'ing destroys the current reference and replaces it with
a new reference to the same object. The destruction of it's current
reference is what causes the SelectedIndex to change and whether one thinks
it is intuitive or not, if you think about it, it is actually logical.

"Alec MacLean" <al**********@NO-SPAM-copeohs.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
Hi,

I have a couple of win forms where I am editing values that are stored in
a SQL database.

I'm using the listbox control to hold the data object each form interacts
with. Each object is defined by my own classes.

On the first form, I use an approach to reduce the number of database
calls. This essentially consists of :

1. Update the values in the database
2. Update the copy of the object currently being edited with the new
values so that is matches the values saved to the db
3. Re-insert the updated object back into the listbox at the same
position.

Step 3 is achieved very simply by the following code:
Me.lbCampaigns.Items.Item(Me.CurrentCampaign.ListP os) = Me.CurrentCampaign

(The ListPos is an integer property of the object class that is set when
the item is selected from the listbox.)

The re-insertion of the object to the listbox causes the
SelectedIndexChanged event to fire (although strictly speaking we have not
moved the selection index). In my case, I handle this event and make a
call to refresh the visual control values with the updated object (this is
a bit redundant as we are not moving between selected items, but I can't
prevent the event firing). The SelectedIndex remains at the original
value as per the users selection.

Ok, so this all seems to work fine.

So, I wanted to use the same process on the second form. I implemented
another class to match the requirements of this form. This class also has
a ListPos property defined to store the SelectedIndex value.

In the same manner as on the first form, I copied the updated object
instance back into the listbox.
Me.lbQModes.Items.Item(Me.CurrentQMode.ListPos) = Me.CurrentQMode

However, for some reason, as soon as the SelectedIndexChanged event
begins, the SelectedIndex value is reset to -1, which then prevents the
subsequent procedures from being able to operate properly as they rely on
being able to identify and use a selected item.

I can find no obvious or sensible reason for why this second form should
cause a different behaviour in the SelectedIndexChanged event, so I have
resorted to making a second database call in order to totally reload the
listbox control, then loop through to find the matching ID of the item
selected and re-selecting it.

This approach seems heavy-handed to me and is especially frustrating given
that it works correctly on the first form. I have checked all properties
of the two different listboxes to see if this might have been a possible
cause, but other than name, anchor, position and size, they are using
identical property settings.

I'm at a loss to explain it - can anyone perhaps indicate where I might be
missing something? Not urgent - as I say I've used a total refresh
approach to get past it, but I would prefer the more elegant solution to
work!

Thanks.

Oct 4 '06 #2

P: n/a
Thanks Stephany,

A very nice explanation - I get it now!

Regards,

Al

"Stephany Young" <noone@localhostwrote in message
news:eJ**************@TK2MSFTNGP06.phx.gbl...
First of all, you have to understand what happens when the selection in a
ListBox, (or various other controls), happens.

If you have no item selected and select an item, the SelectedIndexChanged
fires once.

If you have an item already selected and select another item, the
SelectedIndexChanged fires twice. The first time as the current item
becomes deselected and the SelectedIndex becomes -1 and the second time as
the new item becomes selected. This is easily handled by testing for
SelectedIndex = -1 or SelectedItem IsNothing in the SelectedIndexChanged
event handler.

Using the ListBox, as you are, as a container for a collection of your
Campaign objects is perfectly fine but you have to remember that the that
the ListItem does not contain a Campaign object, rather it contains a
reference to your Campaign object.

Because of this there is no need to 'reinsert', as you call it, when you
update one or more properties of the Campaign object. This can easily be
confirmed by:

CurrentCampaign = CType(lbCampaigns.SelectedItem, Campaign)

CurrentCampaign.ListPos = 12345

Console.WriteLine(CType(lbCampaigns.SelectedItem,
Campaign).ListPos.ToString())

The result should be 12345 and demonstrates that CurrentCampaign and
lbCampaigns.SelectedItem both hold references to the same object without
any need to 'reinsert'.

The act of 'reinsert'ing destroys the current reference and replaces it
with a new reference to the same object. The destruction of it's current
reference is what causes the SelectedIndex to change and whether one
thinks it is intuitive or not, if you think about it, it is actually
logical.

"Alec MacLean" <al**********@NO-SPAM-copeohs.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>Hi,

I have a couple of win forms where I am editing values that are stored in
a SQL database.

I'm using the listbox control to hold the data object each form interacts
with. Each object is defined by my own classes.

On the first form, I use an approach to reduce the number of database
calls. This essentially consists of :

1. Update the values in the database
2. Update the copy of the object currently being edited with the new
values so that is matches the values saved to the db
3. Re-insert the updated object back into the listbox at the same
position.

Step 3 is achieved very simply by the following code:
Me.lbCampaigns.Items.Item(Me.CurrentCampaign.List Pos) =
Me.CurrentCampaign

(The ListPos is an integer property of the object class that is set when
the item is selected from the listbox.)

The re-insertion of the object to the listbox causes the
SelectedIndexChanged event to fire (although strictly speaking we have
not moved the selection index). In my case, I handle this event and make
a call to refresh the visual control values with the updated object (this
is a bit redundant as we are not moving between selected items, but I
can't prevent the event firing). The SelectedIndex remains at the
original value as per the users selection.

Ok, so this all seems to work fine.

So, I wanted to use the same process on the second form. I implemented
another class to match the requirements of this form. This class also
has a ListPos property defined to store the SelectedIndex value.

In the same manner as on the first form, I copied the updated object
instance back into the listbox.
Me.lbQModes.Items.Item(Me.CurrentQMode.ListPos) = Me.CurrentQMode

However, for some reason, as soon as the SelectedIndexChanged event
begins, the SelectedIndex value is reset to -1, which then prevents the
subsequent procedures from being able to operate properly as they rely on
being able to identify and use a selected item.

I can find no obvious or sensible reason for why this second form should
cause a different behaviour in the SelectedIndexChanged event, so I have
resorted to making a second database call in order to totally reload the
listbox control, then loop through to find the matching ID of the item
selected and re-selecting it.

This approach seems heavy-handed to me and is especially frustrating
given that it works correctly on the first form. I have checked all
properties of the two different listboxes to see if this might have been
a possible cause, but other than name, anchor, position and size, they
are using identical property settings.

I'm at a loss to explain it - can anyone perhaps indicate where I might
be missing something? Not urgent - as I say I've used a total refresh
approach to get past it, but I would prefer the more elegant solution to
work!

Thanks.


Oct 4 '06 #3

P: n/a
You can do a "RemoveHandler" then do your stuff then a "AddHandler". This
will prevent the events from firing while you do your thing.
--
Dennis in Houston
"Alec MacLean" wrote:
Thanks Stephany,

A very nice explanation - I get it now!

Regards,

Al

"Stephany Young" <noone@localhostwrote in message
news:eJ**************@TK2MSFTNGP06.phx.gbl...
First of all, you have to understand what happens when the selection in a
ListBox, (or various other controls), happens.

If you have no item selected and select an item, the SelectedIndexChanged
fires once.

If you have an item already selected and select another item, the
SelectedIndexChanged fires twice. The first time as the current item
becomes deselected and the SelectedIndex becomes -1 and the second time as
the new item becomes selected. This is easily handled by testing for
SelectedIndex = -1 or SelectedItem IsNothing in the SelectedIndexChanged
event handler.

Using the ListBox, as you are, as a container for a collection of your
Campaign objects is perfectly fine but you have to remember that the that
the ListItem does not contain a Campaign object, rather it contains a
reference to your Campaign object.

Because of this there is no need to 'reinsert', as you call it, when you
update one or more properties of the Campaign object. This can easily be
confirmed by:

CurrentCampaign = CType(lbCampaigns.SelectedItem, Campaign)

CurrentCampaign.ListPos = 12345

Console.WriteLine(CType(lbCampaigns.SelectedItem,
Campaign).ListPos.ToString())

The result should be 12345 and demonstrates that CurrentCampaign and
lbCampaigns.SelectedItem both hold references to the same object without
any need to 'reinsert'.

The act of 'reinsert'ing destroys the current reference and replaces it
with a new reference to the same object. The destruction of it's current
reference is what causes the SelectedIndex to change and whether one
thinks it is intuitive or not, if you think about it, it is actually
logical.

"Alec MacLean" <al**********@NO-SPAM-copeohs.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
Hi,

I have a couple of win forms where I am editing values that are stored in
a SQL database.

I'm using the listbox control to hold the data object each form interacts
with. Each object is defined by my own classes.

On the first form, I use an approach to reduce the number of database
calls. This essentially consists of :

1. Update the values in the database
2. Update the copy of the object currently being edited with the new
values so that is matches the values saved to the db
3. Re-insert the updated object back into the listbox at the same
position.

Step 3 is achieved very simply by the following code:
Me.lbCampaigns.Items.Item(Me.CurrentCampaign.ListP os) =
Me.CurrentCampaign

(The ListPos is an integer property of the object class that is set when
the item is selected from the listbox.)

The re-insertion of the object to the listbox causes the
SelectedIndexChanged event to fire (although strictly speaking we have
not moved the selection index). In my case, I handle this event and make
a call to refresh the visual control values with the updated object (this
is a bit redundant as we are not moving between selected items, but I
can't prevent the event firing). The SelectedIndex remains at the
original value as per the users selection.

Ok, so this all seems to work fine.

So, I wanted to use the same process on the second form. I implemented
another class to match the requirements of this form. This class also
has a ListPos property defined to store the SelectedIndex value.

In the same manner as on the first form, I copied the updated object
instance back into the listbox.
Me.lbQModes.Items.Item(Me.CurrentQMode.ListPos) = Me.CurrentQMode

However, for some reason, as soon as the SelectedIndexChanged event
begins, the SelectedIndex value is reset to -1, which then prevents the
subsequent procedures from being able to operate properly as they rely on
being able to identify and use a selected item.

I can find no obvious or sensible reason for why this second form should
cause a different behaviour in the SelectedIndexChanged event, so I have
resorted to making a second database call in order to totally reload the
listbox control, then loop through to find the matching ID of the item
selected and re-selecting it.

This approach seems heavy-handed to me and is especially frustrating
given that it works correctly on the first form. I have checked all
properties of the two different listboxes to see if this might have been
a possible cause, but other than name, anchor, position and size, they
are using identical property settings.

I'm at a loss to explain it - can anyone perhaps indicate where I might
be missing something? Not urgent - as I say I've used a total refresh
approach to get past it, but I would prefer the more elegant solution to
work!

Thanks.


Oct 5 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.