473,387 Members | 1,899 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

SelectedIndexChanged causes selectedindex to reset to -1?

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
3 2611
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Edward | last post by:
I am having a terrible time getting anything useful out of a listbox on my web form. I am populating it with the results from Postcode lookup software, and it is showing the results fine. What...
9
by: Steve Wolfie | last post by:
Hi! I am *still* developing an asp.net app that i would like to do the following: i want a user to select a category from a drop down. if they select the last option "other" then i would...
7
by: sparkle | last post by:
Hi Everybody, I'm filling a combobox from a class, which works fine on it's own. But when I insert code to fill in other controls something in the combobox fill is causing the...
2
by: blue_nirvana | last post by:
I use a AddHandler statement in the load event of a form to assoicate a routine with a combobox. When I populate the form, I select the approiate value from the combobox by using...
3
by: martin1 | last post by:
Hi, All, I want user select first item (called All) in listbox, then all other items are selected by SetSelected method, but in loop (see code below) whenever going to SetSelected(), the...
6
by: tbrown | last post by:
I have a combobox with items like this: {one,two,three}. The selected index is 0, so "one" appears in the combobox text. When the user drops down the list, and selects "two", for example, I...
4
by: lakepeir | last post by:
Hello, I have combobox with a selectedindexchanged method that seems to be called when starting the application, launching the form with the combobox and making a change in the drop down box of...
5
by: revbart | last post by:
Yep, that's me. I'll bet I've read a hundred articles somewhere or another, but I just can't get the thing to work. I'm working on a custom solution. One of the major UIs includes a calendar-style...
2
by: tshad | last post by:
In my VS 2003 Windows Forms page, when I initially fill my ComboBox (SystemList), it goes to the SelectedIndexChanged event which calls the Loademails() function. I then call it again in the...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.