Not getting values from grid table when checkbox is checked? - c#

I want to get value of row where checkbox is checked. I am new to C# windows forms and so far unsuccessful. I want to eventually use these row values, so if user selects multiple row and then I should get value for those checked. Also, I have set the selection mode to 'fullrowselect'
Please suggest changes to my code
private void button1_Click(object sender, EventArgs e)
{
StringBuilder ln = new StringBuilder();
dataGridView1.ClearSelection();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (dataGridView1.SelectedRows.Count>0 )
{
ln.Append(row.Cells[1].Value.ToString());
}
else
{
MessageBox.Show("No row is selected!");
break;
}
}
MessageBox.Show("Row Content -" + ln);
}

Having a check-box column in your grid will not change the internal status of any of the rows, so you will need to iterate over them all yourself to evaluate. This should do the trick, although you will need to provide the correct column index for the checkbox column in checkBoxColumnIndex
int checkBoxColumnIndex = nnn; // 0 based index of checkboxcolumn
private void button1_Click(object sender, EventArgs e)
{
List<string> checkedItems = new List<string>();
dataGridView1.ClearSelection();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewCheckBoxCell checkBox= row.Cells[checkBoxColumnIndex] as DataGridViewCheckBoxCell;
if (Convert.ToBoolean(checkBox.Value) == true)
{
checkedItems.Add(row.Cells[1].Value.ToString());
}
}
if (checkItems.Count > 0)
MessageBox.Show("Row Content -\r\n" + String.Join("\r\n", checkedItems));
else
MessageBox.Show("No row is selected!");
}
Admittedly, the List<string> is a heavy construct if all you want to do is print the list, but it would be useful if you need to do further processing on all of the checked values.

The SelectedRows is the count of rows that are selected (or highlited rows), and not the rows that are checked.
The second problem in your code is that you're doing an foreach row, but inside you're using the dataGridView, and not the current row.
This is how your if must be:
private void button1_Click(object sender, EventArgs e)
{
const int checkBoxPosition = 3; //You must type here the position of checkbox.
// Remember, it's zero based.
StringBuilder ln = new StringBuilder();
dataGridView1.ClearSelection();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[checkBoxPosition].Value == true)
{
ln.Append(row.Cells[1].Value.ToString());
}
else
{
MessageBox.Show("No row is selected!");
break;
}
}
MessageBox.Show("Row Content -" + ln);
}

Here is a version of your code that may be what you want..but it is hard to tell because you are talking about selected rows but are clearing the selection before processing the rows!
That makes no sense.. maybe you mean the checked rows? OK, you do, so here you go:
private void button1_Click(object sender, EventArgs e)
{
StringBuilder ln = new StringBuilder();
dataGridView1.ClearSelection();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (((bool?)row.Cells[0].Value) == true)
{
ln.Append(row.Cells[1].FormattedValue);
}
}
if (ln.Length <= 0) MessageBox.Show("No rows are checked!");
else MessageBox.Show("Rows content: " + ln);
}

Related

C# How to select two items with the same name in different datagridview?

enter image description hereI have 2 different datagrid, the first DG1 is my item list and DG2 is the item queues for purchased items. My goal is whenever i click an item in DG2, DG1 is also selected with the same name or id. I want to ignore the index because my item queue is different from item list order.
private void dgItems_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowindex = dgItems.Rows[e.RowIndex].Index;
int columnindex = dgItems.Columns[e.ColumnIndex].Index;
dgItemList.Rows[rowindex].Cells[columnindex].Selected = true;
}
You need to access Value property from both of datagridviews cell like
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowindex = dataGridView1.Rows[e.RowIndex].Index;
int columnindex = dataGridView1.Columns[e.ColumnIndex].Index;
foreach (DataGridViewRow row in dataGridView2.Rows)
row.Selected = false;
var cellValue1 = dataGridView1.Rows[rowindex].Cells[columnindex].Value;
foreach (DataGridViewRow row in dataGridView2.Rows)
{
var cellValue2 = row.Cells[columnindex].Value;
if (cellValue1 == cellValue2)
row.Selected = true;
else
row.Selected = false;
}
}
dataGridView1 is your dgItems and dataGridView2 is your dgItemList.
Edit:
If your both of datagridviews column are on different index then you have to provide column index to match value.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowindex = dataGridView1.Rows[e.RowIndex].Index;
int columnindex = dataGridView1.Columns[1].Index;
foreach (DataGridViewRow row in dataGridView2.Rows)
row.Selected = false;
var cellValue1 = dataGridView1.Rows[rowindex].Cells[1].Value; // 1 <= index of Name column in dgItems
foreach (DataGridViewRow row in dataGridView2.Rows)
{
var cellValue2 = row.Cells[0].Value; // 0 <= index of Name column in dgItemList
if (cellValue1 == cellValue2)
row.Selected = true;
else
row.Selected = false;
}
}
Output:
The easiest way to locate the items by name is to loop through the items in the second list, and return the index of the name that matches your query.
private int FindRowIndex(DataGridView view, string searchValue)
{
foreach(DataGridViewRow row in view)
{
if(row.Cells[1].Value.ToString().Equals(searchValue))
return row.Index;
}
return -1;
}
You then simply use this to control which item is being selected in the second table.
private void dgItems_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowindex = dgItems.Rows[e.RowIndex].Index;
int columnindex = dgItems.Columns[e.ColumnIndex].Index;
dgItemList.Rows[rowindex].Cells[columnindex].Selected = true;
string searchName = dgItemList.Rows[rowindex].Cells.Value.ToString();
int secondRowIndex = FindRowIndex(dgItemList2, searchName);
dgItemList2.Rows[secondRowindex].Cells[columnindex].Selected = true;
}
You can repeat the basic loop to locate an alternative column index if needed. Having a method to refer to gives you the ability to repeat the process if you want to click on an item in list 2, and have it select list 1.

c# how to get the values next to checked datagridview checkboxes?

I have a DataGridView with CheckBox column, my question is how do I get the data next to a checked checkboxes and assign them to a variables in array?
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
if (Convert.ToBoolean(this.dataGridView1.Rows[e.RowIndex].Cells["chkBoxColumn"].Value = true) == true)
{
MessageBox.Show(dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString());
}
}
}
It prints the last checked item over and over.
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (bool.Parse(dataGridView1.Rows[i].Cells["chkBoxColumn"].Value.ToString()) == true)
{
MessageBox.Show(dataGridView1.Rows[i].Cells[1].Value.ToString());
}
}
}
and i'm getting a null reference exception using this.
Edit
Question got changed, so tweaked the code so that the values get put into a list.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
List<string> someList = new List<string>();
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
var cell = row.Cells[e.ColumnIndex] as DataGridViewCheckBoxCell;
if (Convert.ToBoolean(cell.Value) == true)
{
if (cell.State != DataGridViewElementStates.Selected)
{
someList.Add(row.Cells[1].Value.ToString();
}
}
else if (cell.State == DataGridViewElementStates.Selected)
{
someList.Add(row.Cells[1].Value.ToString();
}
}
}
This might do the trick for you, however you'll get a popup every time a user ticks a checkbox, and you'll get as many popup as there are checkboxes that are true.
the problem is in the line
MessageBox.Show(dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString());
e.RowIndex points to the changed row
it should be:
for (int i = 0; i <= this.dataGridView1.Rows)
{
var row = this.dataGridView1.Rows[i]
if (Convert.ToBoolean(this.dataGridView1.Rows[i].Cells["chkBoxColumn"].Value = true) == true)
{
MessageBox.Show(dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString());
}
}
Also, note that you're getting error in your second example because some row is containing a null value in the checkbox column.
Convert.ToBoolean(null) returns false
But bool.Parse(null) throws an exception
I guess something like this ?
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
Stringbuilder text = new StringBuilder();
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
if (Convert.ToBoolean(row.Cells["chkBoxColumn"].Value = true) == true)
{
text.Append(row.Cells[1].Value.ToString());
}
}
MessageBox.Show(text.ToString());
}
EDIT: the question has changed from showing the values to saving them into an array, so I need to change my answer also
Suppose you want all values for Cell[1] saved into an array
and suppose that cell is of type integer.
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
List<int> list = new List<int>();
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
if (Convert.ToBoolean(row.Cells["chkBoxColumn"].Value = true) == true)
{
list.Add(int.Parse(row.Cells[1].Value.ToString()));
}
}
// you now have all values saved into the list
}
You can put the code in a button click and find checked values this way:
private void button1_Click(object sender, EventArgs e)
{
var checkedValues = dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(row => (bool?)row.Cells["Your CheckBox Column Name"].Value == true)
.Select(row => string.Format("{0}", row.Cells["The Other Column Name"].Value))
.ToList();
MessageBox.Show(string.Join(",", checkedValues));
}

Get Values from Datagridview related to to certain values in another column c#

So here is my problem. I have not been coding very long and i have been pulling my hair out on this issue for 2 days now and cant get an answer that works...
Form1 has a datagridview with 3 columns and multiple rows of data.
If i press a button on Form1 i need it to populate all the values in column1 that has a certain value in column[2] and then display it in a textbox on Form2.
Example:
Datagrid example
So if I click a button i want to pull all the amounts for car1 and display the total in a textbox on form2.
Form2 obj = new Form2();
public void button4_Click(object sender, EventArgs e)
{
String searchValue = "Car1";
int rowIndex = 1;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[2].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
obj.Controls["TextBox1"].Text = dataGridView1.Rows[rowIndex].Selected.ToString();
obj.Show();
}
else
{
break;
}
}
}
I just get the answer "true" in my textbox
I hope this makes sense
Thanks in advance
Why do you break foreach loop. As i understand, you want all other amounts of Car1. Right? Check this out:
Form2 obj = new Form2();
public void button4_Click(object sender, EventArgs e)
{
String searchValue = "Car1";
int amount = 0;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if(row.Cells["Type"].Value.ToString().Equals(searchValue)
{
amount+ = Convert.ToInt32(row.Cells["Amount"].Value.ToString())
}
}
if(amount > 0 )
{
obj.Controls["TextBox1"].Text = amount.ToString();
}
else
{
obj.Controls["TextBox1"].Text = "No car found!";
}
obj.Show();
}
Also you need to control if Amount is a number or not.

how select multiple row using shift and Ctrl key in datagridview C#

My requirement : In datagridview I need select row by clicking the row header and selected row should maintain until I will click the other row header also same time I should select cell too.
My Problem : I can't select multiple row using Shift and Ctrl key.
my code :
List< DataGridViewRow> selectedRows = new List< DataGridViewRow>();
void selectRows()
{
dataGridView1.SuspendLayout();
foreach (DataGridViewRow r in dataGridView1.Rows)
{
r.Selected = selectedRows.Contains(r);
}
dataGridView1.ResumeLayout();
}
private void dataGridView1_RowHeaderMouseClick(object sender,DataGridViewCellMouseEventArgs e)
{
DataGridViewRow clickedRow = dataGridView1.CurrentRow;
if (selectedRows.Contains(clickedRow))
{
selectedRows.Remove(clickedRow);
}
else
{
selectedRows.Add(clickedRow);
}
selectRows();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((row.Index != e.RowIndex) && !row.Selected)
{
row.DefaultCellStyle.BackColor = Color.White;
}
else
{
selectedRows.Remove(clickedRow);
row.Selected = true;
row.DefaultCellStyle.BackColor = Color.Blue;
}
}
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.DefaultCellStyle.BackColor == Color.Blue)
{
row.Selected = true;
}
}
}
You have to set your enable your datagridview's multiselect dataGridView.MultiSelect = true;
Be familiar with using a debugger, you will be able to find out where the issue is.
You are clearing the selection in your loop
foreach (DataGridViewRow row in dataGridView1.Rows)
{
}
Rethink the if-else logic in it and you will see why. You are clearing your previous selections when you are not suppose to.

C#. Get all cell in a row by row index in a data grid

I have the row index of a table. I need to get the value of each cell in the row and add it to a list. I can't seem to get it right.
You could iterate through DataGridView rows and add specific index value to a list,
private void button2_Click(object sender, EventArgs e)
{
List<string> items = new List<string>();
foreach (DataGridViewRow item in dataGridView1.Rows)
{
if (null != item && null != item.Cells[0].Value)
{
items.Add(item.Cells[0].Value.ToString());
}
}
}

Categories