|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
SelectedIndexChanged causes selectedindex to reset to -1?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.ListPos) = 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. 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. Show quoteHide quote "Alec MacLean" <alec.maclean@NO-SPAM-copeohs.com> wrote in message news:%23QJyAev5GHA.2264@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.ListPos) = 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. > Thanks Stephany,
A very nice explanation - I get it now! Regards, Al Show quoteHide quote "Stephany Young" <noone@localhost> wrote in message news:eJgle235GHA.4484@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" <alec.maclean@NO-SPAM-copeohs.com> wrote in message > news:%23QJyAev5GHA.2264@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.ListPos) = >> 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. >> > > You can do a "RemoveHandler" then do your stuff then a "AddHandler". This
will prevent the events from firing while you do your thing. -- Show quoteHide quoteDennis in Houston "Alec MacLean" wrote: > Thanks Stephany, > > A very nice explanation - I get it now! > > Regards, > > Al > > "Stephany Young" <noone@localhost> wrote in message > news:eJgle235GHA.4484@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" <alec.maclean@NO-SPAM-copeohs.com> wrote in message > > news:%23QJyAev5GHA.2264@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.ListPos) = > >> 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. > >> > > > > > > >
da.update (syntax error in UPDATE statement)
VB to C# converter RuntimeHelpers.GetObjectValue Discussion [Newbie] Customize Anchor properties ? Newbie Paint Question Focus problem with the tab control Q: Activated Playing Wav-files over 2 soundcards in VB.NET windows control library Controlling XML Structure with XMLSerialization |
|||||||||||||||||||||||