locked
Invalid Argument of 0 for index RRS feed

  • Question

  • Hi, I'm getting this error. I might be asking a question that was already asked, but I can't find it anywhere.

    System.ArgumentOutOfRangeException: InvalidArgument=Value of '0' is not valid for 'index'.

    I am getting the error on the following line, which is located in the "SelectedIndexChanged" event for the ListView lsvDeck :

    Basic_Card l_card = m_Lib[lsvDeck.SelectedIndices[0]];

    That single error is ruining my hopes of successfully finishing the program itself. Any idea of what the problem is?

    If it matters, I'm using .NET Version 4.0.3

    Also, I would like to know if I am wrong to assume that the array of selected indices is emptied and filled again right before that event is called. For instance, if I would start the program, it would start with -1 as the only value of the array, and as soon as I click on the third item of the ListView, the only value of the array would become 2.

    Is it a wrong assumption?

    Monday, October 8, 2012 8:40 PM

Answers


  • The exception is thrown when, in the event, I'm trying to access the new value. Am I wrong to think that the event is triggered by... wait a minute...

    Am I to understand that my bug is caused because I assumed that the event is called once, when it's called twice, right? When the array is emptied, and when they add the new value. It would be quite stupid from me, but I assume it is the most likely error I could have made.

    That is likely the problem.  Depending on how your'e changing the selection, you can fire the event when there is nothing, then it will fire again when the new selection is made.

    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by G-Lafrance Tuesday, October 9, 2012 8:11 PM
    Tuesday, October 9, 2012 7:47 PM
  • This will happen if there are no SelectedIndices.  Make sure the Count is >0 before grabbing this.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by Jason Dot Wang Friday, October 12, 2012 5:00 AM
    • Marked as answer by Jason Dot Wang Tuesday, October 16, 2012 9:11 AM
    Monday, October 8, 2012 8:43 PM

All replies

  • This will happen if there are no SelectedIndices.  Make sure the Count is >0 before grabbing this.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by Jason Dot Wang Friday, October 12, 2012 5:00 AM
    • Marked as answer by Jason Dot Wang Tuesday, October 16, 2012 9:11 AM
    Monday, October 8, 2012 8:43 PM
  •  Make sure the Count is >0 before grabbing this.

    Not to dissuade you from Reed's perfect answer...but doing a full count can be a wastefull process such as to count up thousand(?) of items when the boolean for count > 0 is what is really wanted.

    It is better to use the enumerable extension Any() instead so it doesn't count past the first item. But...before getting a count, always check if null. I do that in an extension which I call ValidWithItems():

    /// <summary>
    /// Does two checks, if not null and if it has items.
    /// </summary>
    /// <returns>True if it is not null and has at least 1 item.</returns>
    public static bool ValidWithItems<T>( this IEnumerable<T> target )
    {
       return ((target != null) && (target.Any()));
    }


    William Wegerson (www.OmegaCoder.Com)

    Monday, October 8, 2012 9:21 PM
  •  Make sure the Count is >0 before grabbing this.

    Not to dissuade you from Reed's perfect answer...but doing a full count can be a wastefull process such as to count up thousand(?) of items when the boolean for count > 0 is what is really wanted.

    It is better to use the enumerable extension Any() instead so it doesn't count past the first item. But...before getting a count, always check if null. I do that in an extension which I call ValidWithItems():

    /// <summary>
    /// Does two checks, if not null and if it has items.
    /// </summary>
    /// <returns>True if it is not null and has at least 1 item.</returns>
    public static bool ValidWithItems<T>( this IEnumerable<T> target )
    {
       return ((target != null) && (target.Any()));
    }


    William Wegerson (www.OmegaCoder.Com)

    In this case, Count is a property on the collection, so it's O(1) - Enumerable.Any() would require a cast (as it's not IEnumerable<T>, only IEnumerable) + force fetching the enumerator....  I'd stick to Count> 0 (for this specific scenario).


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Monday, October 8, 2012 9:27 PM
  • Ahh...the winform SelectedIndices 'collection'. My bad... :-)

    But also verify that m_Lib is not null and contains the total items greater or equal to the value returned by SelectedIndicies[0] when as Reed pointed out, has more than one value.


    William Wegerson (www.OmegaCoder.Com)


    • Edited by OmegaMan Monday, October 8, 2012 9:39 PM
    Monday, October 8, 2012 9:39 PM
  • Well, thanks for your insightful answers. However, here are more specifications :

    I created no null variables in this software. I made sure of it.

    I already use that guard "if (lsvDeck.SelectedIndices.Count > 0)", but the problem is that I use the form to automatically add the newly selected index (via clicking on a line, "details" view). Here is more code, maybe it can help.

    private void lsvDeck_SelectedIndexChanged(object sender, EventArgs e)
    {
        Basic_Card l_card = m_Deck[lsvDeck.SelectedIndices[0]];
    
        //Completely unrelated code, concerning a TextBox elsewhere in the program.
    }

    Upon adding a guard, it becomes :

    private void lsvDeck_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (lsvDeck.SelectedIndices.Count > 0)
        {
            Basic_Card l_card = m_Deck[lsvDeck.SelectedIndices[0]];
    
            //Completely unrelated code, concerning a TextBox elsewhere in the program.
        }
    }

    Also, excuse my error, my first message should have been

    Basic_Card l_card = m_Deck[lsvDeck.SelectedIndices[0]];

    It was also the target piece of code in my program. I just didn't copy/paste the right one. Problem here being the same nonetheless, I believe.


    • Edited by G-Lafrance Monday, October 8, 2012 10:20 PM Forgot one important part.
    Monday, October 8, 2012 10:19 PM
  • Put a break point on the assigment where you are getting the l_card and run the debugger. Verify that m_Deck is valid (not null) and tell us how many items does it contain. Then report what lsvDeck.SelectedIndices[0] contains.

    William Wegerson (www.OmegaCoder.Com)

    Tuesday, October 9, 2012 6:22 AM
  • Put a break point on the assigment where you are getting the l_card and run the debugger. Verify that m_Deck is valid (not null) and tell us how many items does it contain. Then report what lsvDeck.SelectedIndices[0] contains.

    William Wegerson (www.OmegaCoder.Com)

    Already done :

    m_Deck is not null, it contains 16 elements.

    lsvDeck.SelectedIndices contains 0 elements.

    And... There you go.

    Tuesday, October 9, 2012 4:04 PM
  • Put a break point on the assigment where you are getting the l_card and run the debugger. Verify that m_Deck is valid (not null) and tell us how many items does it contain. Then report what lsvDeck.SelectedIndices[0] contains.


    William Wegerson (www.OmegaCoder.Com)

    Already done :

    m_Deck is not null, it contains 16 elements.

    lsvDeck.SelectedIndices contains 0 elements.

    And... There you go.

    And, back to what I said in my first message: "This will happen if there are no SelectedIndices.  Make sure the Count is >0 before grabbing this."

    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Tuesday, October 9, 2012 4:15 PM
  • m_Deck is not null, it contains 16 elements.

    lsvDeck.SelectedIndices contains 0 elements.


    Since lsvDeck.SelectedIndices has zero items and you put in the guard code to anticipate that...where is the exception now being thrown from?


    William Wegerson (www.OmegaCoder.Com)


    • Edited by OmegaMan Tuesday, October 9, 2012 4:24 PM Spelling
    Tuesday, October 9, 2012 4:23 PM
  • Put a break point on the assigment where you are getting the l_card and run the debugger. Verify that m_Deck is valid (not null) and tell us how many items does it contain. Then report what lsvDeck.SelectedIndices[0] contains.


    William Wegerson (www.OmegaCoder.Com)

    Already done :

    m_Deck is not null, it contains 16 elements.

    lsvDeck.SelectedIndices contains 0 elements.

    And... There you go.

    And, back to what I said in my first message: "This will happen if there are no SelectedIndices.  Make sure the Count is >0 before grabbing this."

    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    The problem is the following one :

    I happen to have this code in the event triggered by the change of selected indices. Which means, when the value of the lsvDeck.SelectedIndices[0] is modified from 5 to 2 (for example). However, the event reacts as if the new selected index isn't in the array at all.

    The exception is thrown when, in the event, I'm trying to access the new value. Am I wrong to think that the event is triggered by... wait a minute...

    Am I to understand that my bug is caused because I assumed that the event is called once, when it's called twice, right? When the array is emptied, and when they add the new value. It would be quite stupid from me, but I assume it is the most likely error I could have made.

    • Marked as answer by G-Lafrance Tuesday, October 9, 2012 7:52 PM
    • Unmarked as answer by G-Lafrance Tuesday, October 9, 2012 8:12 PM
    Tuesday, October 9, 2012 7:43 PM

  • The exception is thrown when, in the event, I'm trying to access the new value. Am I wrong to think that the event is triggered by... wait a minute...

    Am I to understand that my bug is caused because I assumed that the event is called once, when it's called twice, right? When the array is emptied, and when they add the new value. It would be quite stupid from me, but I assume it is the most likely error I could have made.

    That is likely the problem.  Depending on how your'e changing the selection, you can fire the event when there is nothing, then it will fire again when the new selection is made.

    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by G-Lafrance Tuesday, October 9, 2012 8:11 PM
    Tuesday, October 9, 2012 7:47 PM
  • Thanks a bunch.
    Tuesday, October 9, 2012 8:12 PM