Check if index of List<List<string>> is not null - c#

I have a List<List<string>>, and a ComboBox with 10 items and when the selected index is changed, I use the comboBox_selectedIndexChanged event to bind the data for this index into a ListBox.
I also have Add and Remove buttons that can insert data to my List<List<string>.
How can I prevent the user from selecting index 5 from the ComboBox and add data for it, if the first four are still empty? E.g. tell him that he has to put data in indexes 1, 2, 3 and 4 first.
The click event for the Add button looks like this:
int selectedIndex = comboBox1.SelectedIndex;
//This throws an exception when the selected index is zero,
//of course it makes sense because we can't check if index 0-1 in myList is null
if (myList.Count >= selectedIndex && myList[selectedIndex - 1] != null)
{
myList[selectedIndex].Add(textEdit1.Text);
}
else
MessageBox.Show("Please fill the previous indexes first.");
I know that I can do it in the SelectedIndexChanged event of the ComboBox, but I prefer to do it here.

What about:
int selectedIndex = comboBox1.SelectedIndex;
if (selectedIndex == 1 || (myList.Count >= selectedIndex && myList[selectedIndex - 1] != null))
{
myList[selectedIndex].Add(textEdit1.Text);
}
else
MessageBox.Show("Please fill the previous indexes first.");
if selectedIndex == 1 is true then it wont test the second parameter in the if statement, and won't throw an error. If it is not 1 it will test the second parameter and your error will not be thrown.

Related

(C#) DataGridView: How to get Selected Count with cells AND rows?

So I have this DataGridView
And This code:
if(dataGridView1.SelectedRows.Count > 1)
{
MessageBox.Show("Error: More than one value selected");
return false;
}
It counts correctly to 2 if I have 2 completly selected rows.
But I want to check if any cells from 2 different rows or more are selected.
In other words:
in my picture my current selection is returning 1 at the moment but i want it to return 2.
Thank you.
Edit after fix: Working code:
if(dataGridView1.SelectedCells.Cast<DataGridViewCell>().Select(c => c.RowIndex).Distinct().Count() > 1)
{
MessageBox.Show("Error: More than one value selected");
return false;
}
To get the number of rows with selected cells :
int count = dataGridView1.SelectedCells.Cast<DataGridViewCell>()
.Select(c => c.RowIndex).Distinct().Count();
To check if more than one row is selected:
var selectedCells = dataGridView1.SelectedCells;
bool check = selectedCells.Count > 0
&& selectedCells.Cast<DataGridViewCell>().Any(c => c.RowIndex != selectedCells[0].RowIndex);
If you have a fairly standard setup where each column is bound to a property of your backing data object, and each row represents one object, the following should work:
dataGridView1.SelectedCells.Select(c => c.Item).Distinct().Count()
This will return the number of items the different cells are bound to. Since each item has one row that binds to it, it will return the count of every row with at least one selected cell.

InvalidArgument=Value '18' is invalid to 'SelectedIndex' Parameter name: SelectedIndex

I have a Button where I am able to save data into the database. To do that I will get the information on Combobox and on a Textbox. I got a collection of items iniside of the Combobox and cannot be changed at the moment.
Right now, I have 17 items and every time I save something it will pull to the next item using cmbID.SelectedIndex += 1;, but every time I pull to the last item from Combobox it will give me an error :
InvalidArgument=Value '18' is invalid to 'SelectedIndex' Parameter name: SelectedIndex
To solve it I've tried to use an if statement:
if (cmbID.SelectedIndex >= 18)
{
cmbID.SelectedIndex = 1;
}
But this is not working, basically if the Combobox reach '18' it should go back to the SelectedIndex choosen by me.
Do you guys have any idea I can solve this problem?
You can't have index more than (item count -1) for the combobox, so
if(cmbID.SelectedIndex == (cmbID.Items.Count - 1))
{
cmbID.SelectedIndex =1;
}else
{
cmbID.SelectedIndex += 1;
}

how to check there is a row in specific index to avoid IndexOutOfRangeException

I want to to know how to check there is a row in specific index to avoid the following exception :
System.IndexOutOfRangeException
for example :
if (dtNew != null && dtNew.Rows.Count > 0 )
{
if (dtNew.Rows[i][0] != null)
{
row["newEmp"] = dtNew.Rows[i][0];
}
else
{
row["newEmp"] = 0;
}
}
What if dtNew has just a one row and the i = 3 !!
Well if you want to get to row i, you need to change your check from
&& dtNew.Rows.Count > 0
to
&& dtNew.Rows.Count > i
Currently you're only checking whether there are any rows - i.e. whether dtNew.Rows[0] is valid.
(Do you definitely need to check for dtNew being null? Is that a valid program state? Likewise is it valid for the row to exist but column 0 to not be populated? You may be able to make your code much simpler.)

How to remove more items from combobox?

I am trying to remove more items from a combobox but the application is only removing one item at a time.
The combobox has a list of email addresses. I want to remove empty items (""), and those that don't have # inside of text.
Code below only removes one item at a time.
for (int i = 0; i < cmbTo.Items.Count; i++)
{
string st = cmbTo.Items[i].ToString();
if (st == "" || st.IndexOf("#") == -1)
{
cmbTo.Items.RemoveAt(i);
}
}
How can I rewrite this?
Hint: Think about what happens to the i variable when you remove an item
...
When you RemoveAt an item, the item is removed, and every subsequent item moves up one index. Your loop then hits the bottom, where it goes back to the top, increments i, and moves on.
Result? You just skipped an item. If this is the last item in the list, then the loop exists.
Instead, manually decrement i to offset your removal, so that everything works:
for (int i = 0; i < cmbTo.Items.Count; i++)
{
string st = cmbTo.Items[i].ToString();
if (st == "" || st.IndexOf("#") == -1)
{
cmbTo.Items.RemoveAt(i);
i--;
}
}
Your code doesn't work because the moment you remove an item from the collection, the Count() decreases and the for loop exits before going through all the list of items.
You need to first create a list of elements to remove (put them in a temp list) and then iterate through the newly created list calling cmbTo.Items.Remove(currentElement);
When you remove an item from a combobox, the indices of the following items change and your item count will change. Could that account for the behavior you're seeing?
Just do the removal in the opposite direction (i.e. from the end to the front), and you won't need to worry about adjusting i1 when the item is removed:
var items = cmbTo.Items;
int i = items.Count;
while (i > 0) {
--i;
string st = items[i].ToString();
if (st == "" || st.IndexOf("#") < 0)
items.RemoveAt(i);
}
1 Which you currently don't do, so some items that should potentially be removed are skipped, which causes your problem.

How can I tell if at least one dataGridView row is selected c#

I have a program that takes a value from the selected row in a dataGridView and passes it to a function. However, the gridView could be empty or could not have a row selected.
I took care of the empty Grid, but I was wondering if there is a way if I can tell if any row is selected.
I tried this:
if (Convert.ToInt32(dataGridView1.Rows.Count) > 0)
{
//It is not empty
}
int c = dataGridView1.SelectedRows.Count(); //this line gives me an error
if (c>0)
{
//there is a row selected
}
Do you know how can I solve this?
You simply remove the parenthesis after the "Count" keyword. It should look like this:
if (Convert.ToInt32(dataGridView1.Rows.Count) > 0)
{
//It is not empty
}
int c = dataGridView1.SelectedRows.Count; //remove parenthesis here
if (c>0)
{
//there is a row selected
}
if (dataGridView1.Rows.Count > 0 && dataGridView1.SelectedRows.Count > 0) {
......
}

Categories