ListBox is a listbox
ServerClient is an instance of a class which has arraylist
Arraylist pclist = new Arraylist();
temping is array of strings as
strings[] temping = new string[6];
Now, during execution... The error I get is:
"Additional information: Object reference not set to an instance of an object."
this.ListBox.Invoke(new MethodInvoker(delegate
{
for (int i = 0; i < ServerClient.pclist.Count; i++)
{
// I am Alive,MyPcName,192.168.1.1,Status,NickName,datetime
temp = ServerClient.pclist[i].ToString();
temping = temp.Split(',');
ListBox.Items.Add(temping[4] + "( " + temping[3] + " )");
}
for (int i = ServerClient.pclist.Count; i < ListBox.Items.Count; i++)
{
ListBox.Items.RemoveAt(i);
}
}));
If I were you I'd split my Invoke function up so that the called delegate function is declared elsewhere. Having an inline function declaration like this can be bad enough to debug, but a delegate is doubly so.
I think that you'll find that by declaring your in line function in this way the compiler is assigning all variables as locals, which won't have been intialised before use.
When you remove items with RemoveAt in the last loop you have to go down instead of up, because the index of the last item decreases everytime you remove an item with RemoveAt. If you loop down this won't affect the outcome:
for (int i = ListBox.Items.Count - 1; i >= ServerClient.pclist.Count; i--)
{
ListBox.Items.RemoveAt(i);
}
Related
I am trying to show multiple things in a textbox in my software and its just printing out 1 / 5
I think I got the for loop all mixed up so here is how it looks
var getTopFive = new FirefoxDriver();
getTopFive.Navigate().GoToUrl("https://www.tradingview.com/");
IList<IWebElement> movies = getTopFive.FindElements(By.CssSelector("tbody tr"));
for (int i = 0; i < 1; ++i)
{
activeTextBox.Text = movies[i].Text;
}
This is what I tried and failed with.
I tried adding another
activeTextBox.Text = movies[i].Text;
Which did not work
I also tried adding a second block of the same code showed at the top but with a different name for the int etc.
Then I tried adding a else if below it which gave me another error.
So my question is, how do I make the loop go through all the 5 items instead of just showing the first one which it does by this line of code right here.
for (int i = 0; i < 1; ++i)
{
activeTextBox.Text = movies[i].Text;
}
There are two issues here. The first is your for loop is only going to happen once because for(int i = 0; i < 1; i++).
To loop more than once, you need to change to 1 to something else. If you want it dynamic, use for(int i = 0; i < movies.Count; i++).
The second issue is activeTextBox.Text is being over-written each time you write to it. No matter how many times you repeat the loop or the line, the only thing that text box will show is the last item in the loop.
If you want it to show all items, you need to do something like:
activeTextBox.Text += movies[i].Text + "\n";
The \n will put each movie on a separate line - you could use a hyphen or similar to separate each item.
IList has a property called Count. This property returns the number of elements in the list. Use it in your loop like this to show all movies:
for (int i = 0; i < movies.Count; i++)
{
activeTextBox.Text = movies[i].Text;
}
A second way is to use a foreach loop like this:
foreach (IWebElement WebElement in movies)
{
activeTextBox.Text = WebElement.Text;
}
Remember you are overwriting your text each loop. So in the end your text will be the last item of your loop. If you want to add the names behind each other do it like this (seperated with a minus)
activeTextBox.Text += " - " + movies[i].Text;
or this
activeTextBox.Text += " - " + WebElement.Text
clear the Text before your loop with
activeTextBox.Text.Clear();
Try using this code (don't forget to add using System.Linq;):
activeTextBox.Text = string.Join("; ", movies.Select(x => x.Text));
Explanation:
movies.Select(x => x.Text) takes every IWebElement (movie) and return its Text property. So you end up with a list of movie names instead of IWebElement objects.
Next, you join those movies together into a single string, separated by semicolon. (string.Join("; ", ...))
And then you assign the result to the activeTextBox.
I have list that contains custom class elements. I want to assign one of the element's property to a variable.
The following code works:
string myVar = list[0].MyType.MyStringProperty;
However I want to repeat this process for the rest of the list, so I intend to use a loop.
This code however, does not work, as it throws an ArgumentOutOfRange exception:
for(int i=0; i<=list.Count; i++)
{
myVar = list[i].MyType.MyStringProperty;
}
How to resolve this problem?
EDIT:
The exception is thrown at the first execution of loop, at the last line. During debug, the elements in the list seem to be okay. They all have the required string type properties with values (other than null). It is possible, that it has something to do with rows, however I use this exact same method to add new rows in the code elsewhere, and it works perfectly fine (those data are not taken from lists however).
private void MyMethod(List<MyType> list)
{
for (int i = 1; i < list.Count; i++)
{
DataRow newrow = datatable.NewRow();
newrow["Column"] = list[i].MyStringProperty;
}
}
You've got a Off-by-one error in your code.
Change
for(int i=0; i <= list.Count; i++)// <=
to
for(int i=0; i < list.Count; i++)// Note <= is changed to <
Your condition is i<=list.Count which means for loop will execute when i is equal to list.Count in which case you'll get exception because List<T> is zero based.
Why is this not working?
List<int> test = new List<int>();
for (int i = 0; i < 20; ++i)
test.Add(i);
test.ForEach(t => t = ++t);
The elements in test are not incremented.
Firstly, List<T>.ForEach isn't part of LINQ. It's been in .NET since 2.0.
Elements in test are not incremented
No, they wouldn't be. The parameter to Action<T> is passed by value, not by reference. Changes made to the parameter (t in your case) aren't visible to the calling code - and even if they were, there's no guarantee that List<T>.ForEach would use them.
Note that if you had a reference type (e.g. StringBuilder) as the list element type, and made changes to the data in the object that the parameter value referred to, e.g.
builders.ForEach(x => x.Append("Foo"))
then those changes would be visible in the list, because they're not changes to the list at all - the list would contain the same references as before, just to objects whose data happened to have changed.
Ints are values, not references.
Plus a foreach doesn't allow manipulation of the collection elements.
So it's a double fail i'm afraid :(
What would work:
for(int i=0;i<test.Count;i++)
test[i]++;
The t variable that you have is a copy of the item in the list. You are modifying a copy, and as such the item in the list itself isn't affected. To increment each item in the list you can use a for loop:
for(int i = 0; i < test.Count;i++
test[i]++;
This is the expected result.
You wouldn't expect the following to actually increment x in Main, so your lambda example is no different.
static void Main(string[] args)
{
int x = 1;
Increment(x);
Console.WriteLine("{0}");
}
static void Increment(int x)
{
x = ++x;
}
List<int> test = new List<int>();
for (int i = 0; i < 20; ++i)
test.Add(i);
for(var z = 0 ; z < test.Count; z++)
{
test[z]++;
}
Problem is that after Randomize func, array forcombo equals random_for_combo, but I do not equate them anywhere. Please help.
private void button1_Click(object sender, EventArgs e)
{
string sub = "1#2#3#4#5#6#7#8#9#10";
string[] split = sub.Split('#');
string[] forcombo = new string[split.Length / 2];
int s = 0;
for (int j = 1; j <= split.Length - 1; j += 2)
{
forcombo[s] = split[j];
s++;
}
string[] random_for_combo = new string[forcombo.Length];
random_for_combo = forcombo;
MessageBox.Show(forcombo[0] + forcombo[1] + forcombo[2] + forcombo[3] + forcombo[4], "Before random");
random_for_combo = RandomizeStrings(random_for_combo);
MessageBox.Show(forcombo[0]+forcombo[1]+forcombo[2]+forcombo[3]+forcombo[4], "After random");
}
public static string[] RandomizeStrings(string[] arr)
{
ArrayList l1 = new ArrayList(arr.Length);
ArrayList l2 = new ArrayList(arr.Length);
foreach (object k in arr)
{
l1.Add(k.ToString());
}
while (l1.Count > 0)
{
Random rnd = new Random();
int rand = rnd.Next(l1.Count);
l2.Add(l1[rand]);
l1.RemoveAt(rand);
Thread.Sleep(rnd.Next(50));
}
for (int i = 0; i < l2.Count; i++)
{
arr[i] = l2[i].ToString();
}
return arr;
}
Some helpless info to complete question..
There's a couple of problems with this code:
You're copying the reference from one array variable into another:
random_for_combo = forcombo;
This does not make the two variables contain two arrays that contain the same values, the two values now refer to the same one array in memory. Change one, and it will appear the other one changed as well. Think of the two variables as postit notes with the address of a house on them, the same address. If you go to the house and rearrange the furniture, "both houses" will appear to be changed. There is only one house however.
When you pass the array to the randomize method, you're passing a reference to the array, not a copy of the array, which means that if you change the contents of the array, you're not working on a copy, you're working on the original. This means that the array you get passed, and the array you return, is the same one array in memory
Probably not the source of the bugs in your question, but you shouldn't construct new Random objects every time you use it in a loop, instead construct it once and reuse, otherwise you risk getting back just a few distinct values.
Lastly, if your gut reaction is "this is a bug in visual studio or C#", then it almost never is, always work on the presumption that it is your own code that is faulty. By "almost never" I would say that the chance of you hitting a bug in C# or Visual Studio by chance is none.
To make a new array with the same contents of another, you have a few options:
Explicitly make an array and copy over the elements one by one:
random_for_combo = new string[forcombo.Length];
for (int i = 0; i < forcombo.Length; i++)
random_for_combo[i] = forcombo[i];
Use Array.Copy instead of the for-loop:
random_for_combo = new string[forcombo.Length];
Array.Copy(forcombo, random_for_combo, forcombo.Length);
Use the new Linq ToArray extension method:
random_for_combo = forcombo.ToArray();
Note that even though this looks like a no-op (since forcombo is an array), you'll actually get a new array with the same contents.
but you did here :
random_for_combo = forcombo;
you set random_for_combo so it point to forcombo.
if you want to use the original array than you need to copy it to new array
something like this (instead of the above line)
string[] random_for_combo = new string[forcombo.Length];
for (int i = 0; i < forcombo.Length; i++)
{
random_for_combo[i] = forcombo[i];
}
So i get this error at the textbox assignation but i don't understand why, can anyone give me an advice on what to do?
private void button2_Click(object sender, EventArgs e)
{
int n = Convert.ToInt32(textBox16.Text);
int t = Convert.ToInt32(textBox17.Text);
matrix.CalculeazaQR(n, t);
string temp;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
temp = matrix.q[i, j].ToString("0.00");
if (j % (n - 1) == 0)
temp += "\n";
temp += ",";
}
}
textBox3.Text = temp;
}
You are assigning temp inside the for loop and compiler can't determine whether you will get inside the loop or not. You may initialize the temp on top like:
string temp = string.Empty;
Statements inside the loop would only execute if the condition is true and the compiler at compile time can't determine whether the condition will be true or not, it will consider the temp to remain unassigned, hence the error.
put like this:
string temp="";
you have to assign string(or any variable) to empty or something before you actually use it.
"can anyone give me an advice on what to do?"
Well, Initialize text:
string temp = string.Empty;
The compiler has no way of knowing if temp (which is used on textBox3.Text = temp;) has a value after the loops (for instance, when n < 1).
For one thing, your loop is broken to start with - only the very last iteration will matter (i.e. when both i and j are n - 1) as you're replacing the value of temp completely.
But the compiler doesn't know that n is positive - it doesn't know that you'll ever get into the loop. In general, the compiler will never assume that you enter the body of an if statement, a for statement, a while statement or a foreach loop - so any assignments made within those bodies don't affect whether a local variable is definitely assigned or not at the end of the statement... and a local variable has to be definitely assigned before you can read from it (as you're doing at the end of the method).
I suspect you actually want a StringBuilder which you append to within the loop:
StringBuilder builder = new StringBuilder();
for (...)
{
for (...)
{
builder.AppendFormat("{0:0.00},", matrix.q[i, j]);
}
builder.Append("\n");
}
textBox3.Test = builder.ToString();