Can't seem to be able to set ListViewItem.imageIndex - c#

I have been scratching my head with this error for at least an hour, what the heck is wrong here?
In a loop:
if (selectedItems[x].ImageIndex == 3)
{
List<ListViewItem> dupes = CP.listCache.FindAll(delegate(ListViewItem item) { return item.Text == selectedItems[x].Text; });
if (dupes != null && dupes.Count == 1)
dupes[0].ImageIndex = 0;
}
I can access the imageIndex, but not set it. ArgumentOutOfRange exception occurs.

Make sure you know what what's throwing your ArgumentOutOfRange exception -- that's your first problem. Is x a valid index into selectedItems? Is the index you're setting into your image list valid? Remember, indexes are zero-based, not 1-based.

Related

Null-coalescing operator inside ternary

I have this C# code:
data[j].Actual[0] = data[j].Actual.Count != 0 ? (data[j].Actual[0] ?? 0) : 0;
What I want to do is to check if the count is 0, in this case the value of the variable should be set on 0.
In case the count is different of 0, I want to check with null-coalescing operator if that value is there, otherwise return 0.
The problem I have is that I get this error message:
Index was out of range. Must be non-negative and less than the size of
the collection. Parameter name: index
My guess is that even when data[j].Actual.Count is 0 it doesn't the result to 0 but it tries to do something with the null-coalescing operator.
Any suggestions?
I think the problem is the assignment; if data[j].Actual is an empty (list/array/whatever), then you can't just assign data[j].Actual[0] to anything. If this is an array, you can't do anything (except maybe create a new array). If this is a list, you would need to .Add a value.
I would simplify the code:
var actual = data[j].Actual;
if (actual.Count == 0)
{
actual.Add(0);
// or if this is an array: data[j].Actual = new double?[] {0};
}
else if (actual[0] == null)
{
actual[0] = 0;
}
This isn't one line, but it is easy to understand.
look carefully
data[j].Actual[0] = data[j].Actual.Count != 0 ? (data[j].Actual[0] ?? 0) : 0;
You are assigning to Actual[0]. if Actual.Count is 0 you get out of range exception. you cant use ternary. use if statement.
if(data[j].Actual.Count != 0)
{
data[j].Actual[0] = data[j].Actual[0] ?? 0;
}
// else you don't need to set anything because there is nothing to set!

C# Error Additional information: The enumeration has already completed

This is my first time using the enumerator interface.
I am Trying to look threw a stack to find next occurrence of a string.
The loop is suppose to loop threw my tags stack and find out if a tag inside my stack is a tag i was looking for. Once the stack gets to the last tag in the stack it crashes and issues the error in the title. The last tag in the list also happens to be the first match for lookforthisTag string variable. I want the while look to exit when the if statement finds a match or when all stack items have been compared.
/*find next opening tag in stack */
int I = 1;
var enumerator = tags.GetEnumerator(); /// create a enumerator variable
/// move to the next tag in stack
while ( enumerator.MoveNext() != false || found == true || I <= countofTags)
{
htmlTags currentTag = enumerator.Current; // this line causes error.
if (currentTag.open_tag == lookforthisTag)
{
found = true;
}
I++;
}///End while.
This line
while ( enumerator.MoveNext() != false || found == true || I <= countofTags)
will execute the following logic
Does the enumerator returns true? If yes enter the loop else check
next condtion
Is found == true? If yes enter the loop, else check the next condition
Is I <= countofTags? If yes enter the loop, else exit the loop
As you can see even when the enumerator return false it enters the loop because at that point found is true, but inside the loop you call enumerator.Current and this triggers the error message.
Probably you want
while ( !found && enumerator.MoveNext() && I <= countofTags)
Consider that a normal foreach loop would do the same
htmlTags found = null;
foreach(htmlTags currentTag in tags)
{
if (currentTag.open_tag == lookforthisTag)
{
found = currentTag;
break;
}
}
if(found != null)
{
// got it...
}
or just using Linq
htmlTags found = tags.FirstOrDefault(x => x.open_tag == lookforthisTag)
if(found != null)
{
// you have found your tag.
}
I want also to mention the fact that your I <= countOfTags logic
doesn't seem to have any utility in the code shown. The variable I will be always equal to the countOfTags (or just simply equal to tags.Count) because you don't break the loop and continue till the end of the enumeration. If you want to know the 'position' of the found tag, just increment it.
I would rewrite your while condition like this:
while ( enumerator.MoveNext() && !found && I < countofTags)
Or just use linq:
tags.Single (currentTag == currentTag.open_tag == lookforthisTag)
The condition in the while will be true even if enumerator.MoveNext() will be false, because of the or conditions.
It can probably be fixed with changing the condition and also using break to get out of the loop.
like this:
while ( enumerator.MoveNext() && I <= countofTags)
{
htmlTags currentTag = enumerator.Current; // this line causes error.
if (currentTag.open_tag == lookforthisTag)
{
found = true;
break;
}
I++;
}///End while.
But, i wouldn't go this way in the first place.
Use LINQ:
var myItem = tags.FirstOrDefault(currentTag=> currentTag.open_tag == lookforthisTag);

Specified cast is not valid while accessing column value

I am finding records in datatable. If the record matches then I want to compare value in the datarow and do some operation. Please see my code below for better explanation,
foreach (DataRow row2 in dtTo.Rows)
{
DataRow[] match = dtReturn.Select("Id = " + row2["Id"]);
if (match.Length > 0)
{
if (match[0]["boolInt"] == 1) // Getting error on this line
{
match[0]["NewValues"] = "";
}
}
}
I was getting error on below line
if (match[0]["boolInt"] == 1)
Then resharper suggested me to cast to bool. so I changed above line to
if( (bool) (match[0]["bClosed"] = 1))
But when I run the project I get run time error as "Specified cast is not valid" on above line.
In immediate window I get value as 1 when I type ,
(match[0]["bClosed"]
What should i do to get rid of this error?
According this:
No there wont be null. The field is tinyint
you code should look like this (AFAIR, tinyint in SQL server matches byte in CLR):
if ((byte)(match[0]["boolInt"]) == 1)
{
}
If you know the field type, there's no need to call Convert methods. The faster way is to cast directly to that known type.
You need to convert the value to int. You can do it like this:
if (Convert.ToInt32(match[0]["boolInt"]) == 1)
But if the column contains a value that can't be casted you wil get an error.
A better aproach would be:
int number;
bool result = Int32.TryParse(match[0]["boolInt"], out number);
if (result && number == 1)
Try this:
if ((match[0]["boolInt"] as int?) == 1)
{
match[0]["NewValues"] = "";
}
if value is null or not valid int it won't cause exception, but should be handled anyways.

InvalidArgument error when calling LINQ First() method

So my problem is that i am getting an invalid argument error in this section of code. What it is meant to do is take a hand of cards and get the sum of their total value. Then if the value is greater than 21 it checks to see if any of the cards in the hand is an ace(or the type is == ace and it's card totalVal == 11) now my problem is the statement i have written for this will run regardless of if there is an ace in the hand or not and throws an error.
I was wondering if there is any other way i can write the statement below in order to get this to run correctly?
public int HandTotal()
{
int total = CurrentCards.Sum(n => n.Total);
**while ( total > 21 && CurrentCards.First(n => n.Type == 13 && n.Total == 11) !=null)**
{
CurrentCards.First(n => n.Type == 13).Total = 1;
total = CurrentCards.Sum(n => n.Total);
return total;
}
return total;
}
i've tried several different things including changing the != null into > 0 however that throws an invalid argument error saying that > cannot be used with this statement. Is there any other way that i can determine if CurrentCards.First(n => n.Type == 13 && n.Total == 11) is true or false?
Any help or suggestions are greatly appreciated.
Thank You
Instead of First, use Any with the predicate.
while(total > 21 && CurrentCards.Any(n => n.Type == 13 && n.Total == 11))
The First method throws an exception if there are no matching element.
You need to call FirstOrDefault, which can return null.
You should try using FirstOrDefault instead of First.First will throw an error if no elements a returned.
Also check that CurrentCards is not empty. Both First and FirstOrDefault will give an ArguementNullException if the IEnumumerable is empty.

Are variables shared in recursive functions

I'm trying to calculate the number of success cases within a recursive function in C#, but I'm astonished by the fact that my variable is shared between all the function calls!
[update 2]
More than strange this time. doing so
i = i + validTreesFun(tree.Nodes, newWords.ToList()) ;
resets i to 0
doing this
i = validTreesFun(tree.Nodes, newWords.ToList()) + i ;
gives some results (I'm not sure if it's correct)
[updated : the full code]
public static int validTreesFun(List<Tree<char>> nodes, List<string> words)
{
int i = 0;
if (nodes == null && (words == null || words.Count == 0 || (words.Count == 1 && words.First() == "")))
return 1;
else
if (nodes == null)
return 0;
foreach (Tree<char> tree in nodes)
{
var validWords = words.Where(w => w.ToCharArray()[0] == tree.Root)
.Select(w => w);
if (validWords.Count() == 0)
return 0;
else
{
var newWords = validWords.Select(w => join( w.ToCharArray().Skip(1).ToArray()));
i += validTreesFun(tree.Nodes, newWords.ToList());
}
}
return i;
}
when debuging the variable i take the value 1 but it resets to 0 on the next iteration!!
despite the use of
i = i + ....
What is the problem in that piece of code?
Thank you
if (validWords.Count() == 0)
return 0;
Should be
if (validWords.Count() == 0)
continue;
Also, in general, I personally think it is nicer looking to only send in one element at a time to a recursive function.
public static int validTreesFun(Tree<char> node, List<string> words)
That way you don't get the same kind of mistake like above. Finally, a minor note.
w => w.ToCharArray()[0] == tree.Root
can be written as
w => w[0] = tree.Root
No local variables are not at all shared between recursive calls, you should consider some other design problem, inside and after your foreach loop, I dont see any return statements, can you post full code.
Ok, in debugging you will always observe i's current method's value, debugging is not good in recursive functions, its little hard to understand, you will have to move your control down in Call Stack in order to actually observe value of earlier caller of current function.
I would advice you to output Trace or on log file with your level of node, that will help you actual debugging.
Please use TRACE Statement as follow..
Trace.WriteLine(string.Format("{0},{1}",tree.Name,i));
Local variables are not being shared.
What you are seeing (the reset to 0) is the value of i in the (recursively) called function validTreesFun (i gets set to 0 at the start of the function).
Just looking at your code, I think a possible bug might be in someTestHere - if that is never true, then i will stay 0 in the outer scope. Otherwise it should increment by 1 for each true test.
When you are in debug mode, you indeed see that the i is reseted for the call but remain to the wanted value for the caller. Eg , the stack :
validTreesFun --i = 0 for this one
validTreesFun --i = x for this one, but if you do not go trow the calling stack, you will see 0, which is the good value for the top of the stack

Categories

Resources