DataGridView checkbox column - value and functionality - c#

I've added a checkbox column to a DataGridView in my C# form. The function needs to be dynamic - you select a customer and that brings up all of their items that could be serviced, and you select which of them you wish to be serviced this time around.
Anyway, the code will now add a chckbox to the beginning of the DGV. What I need to know is the following:
1) How do I make it so that the whole column is "checked" by default?
2) How can I make sure I'm only getting values from the "checked" rows when I click on a button just below the DGV?
Here's the code to get the column inserted:
DataGridViewCheckBoxColumn doWork = new DataGridViewCheckBoxColumn();
doWork.HeaderText = "Include Dog";
doWork.FalseValue = "0";
doWork.TrueValue = "1";
dataGridView1.Columns.Insert(0, doWork);
So what next?
Any help would be greatly appreciated!

There is no way to do that directly. Once you have your data in the grid, you can loop through the rows and check each box like this:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
row.Cells[CheckBoxColumn1.Name].Value = true;
}
The Click event might look something like this:
private void button1_Click(object sender, EventArgs e)
{
List<DataGridViewRow> rows_with_checked_column = new List<DataGridViewRow>();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (Convert.ToBoolean(row.Cells[CheckBoxColumn1.Name].Value) == true)
{
rows_with_checked_column.Add(row);
}
}
// Do what you want with the check rows
}

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCheckBoxCell ch1 = new DataGridViewCheckBoxCell();
ch1 = (DataGridViewCheckBoxCell)dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[0];
if (ch1.Value == null)
ch1.Value=false;
switch (ch1.Value.ToString())
{
case "True":
ch1.Value = false;
break;
case "False":
ch1.Value = true;
break;
}
MessageBox.Show(ch1.Value.ToString());
}
best solution to find if the checkbox in the datagridview is checked or not.

it took me a long time to figure out how to do this without having to loop through all the records. I have a bound datagridview-source, and all fields are bound except for the checkbox-column. So I don't have/need a loop to add each row and I didn't want to create one just for this purpuse. So after a lot of trying I finally got it. And it's actually very simple too:
First you add a new .cs File to your project with a custom-checkbox cell, e.g.
DataGridViewCheckboxCellFilter.cs:
using System.Windows.Forms;
namespace MyNamespace {
public class DataGridViewCheckboxCellFilter : DataGridViewCheckBoxCell {
public DataGridViewCheckboxCellFilter() : base() {
this.FalseValue = 0;
this.TrueValue = 1;
this.Value = TrueValue;
}
}
}
After this, on your GridView, where you add the checkbox-column, you do:
// add checkboxes
DataGridViewCheckBoxColumn col_chkbox = new DataGridViewCheckBoxColumn();
{
col_chkbox.HeaderText = "X";
col_chkbox.Name = "checked";
col_chkbox.CellTemplate = new DataGridViewCheckboxCellFilter();
}
this.Columns.Add(col_chkbox);
And that's it! Everytime your checkboxes get added in a new row, they'll be set to true.
Enjoy!

Here's a one liner answer for this question
List<DataGridViewRow> list = DataGridView1.Rows.Cast<DataGridViewRow>().Where(k => Convert.ToBoolean(k.Cells[CheckBoxColumn1.Name].Value) == true).ToList();

If you try it on CellContentClick Event
Use:
dataGridView1.EndEdit(); //Stop editing of cell.
MessageBox.Show("0 = " + dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString());

If you have a gridview containing more than one checkbox ....
you should try this ....
Object[] o=new Object[6];
for (int i = 0; i < dgverlist.RowCount; i++)
{
for (int j = 2; j < dgverlist.ColumnCount; j++)
{
DataGridViewCheckBoxCell ch1 = new DataGridViewCheckBoxCell();
ch1 = (DataGridViewCheckBoxCell)dgverlist.Rows[i].Cells[j];
if (ch1.Value != null)
{
o[i] = ch1.OwningColumn.HeaderText.ToString();
MessageBox.Show(o[i].ToString());
}
}
}

1) How do I make it so that the whole column is "checked" by default?
var doWork = new DataGridViewCheckBoxColumn();
doWork.Name = "IncludeDog" //Added so you can find the column in a row
doWork.HeaderText = "Include Dog";
doWork.FalseValue = "0";
doWork.TrueValue = "1";
//Make the default checked
doWork.CellTemplate.Value = true;
doWork.CellTemplate.Style.NullValue = true;
dataGridView1.Columns.Insert(0, doWork);
2) How can I make sure I'm only getting values from the "checked" rows?
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.IsNewRow) continue;//If editing is enabled, skip the new row
//The Cell's Value gets it wrong with the true default, it will return
//false until the cell changes so use FormattedValue instead.
if (Convert.ToBoolean(row.Cells["IncludeDog"].FormattedValue))
{
//Do stuff with row
}
}

To test if the column is checked or not:
for (int i = 0; i < dgvName.Rows.Count; i++)
{
if ((bool)dgvName.Rows[i].Cells[8].Value)
{
// Column is checked
}
}

if u make this column in sql database (bit) as a data type u should edit this code
DataGridViewCheckBoxColumn doWork = new DataGridViewCheckBoxColumn();
doWork.HeaderText = "Include Dog";
doWork.FalseValue = "0";
doWork.TrueValue = "1";
dataGridView1.Columns.Insert(0, doWork);
with this
DataGridViewCheckBoxColumn doWork = new DataGridViewCheckBoxColumn();
doWork.HeaderText = "Include Dog";
doWork.FalseValue = "False";
doWork.TrueValue = "True";
dataGridView1.Columns.Insert(0, doWork);

It is quite simple
DataGridViewCheckBoxCell checkedCell = (DataGridViewCheckBoxCell) grdData.Rows[e.RowIndex].Cells["grdChkEnable"];
bool isEnabled = false;
if (checkedCell.AccessibilityObject.State.HasFlag(AccessibleStates.Checked))
{
isEnabled = true;
}
if (isEnabled)
{
// do your business process;
}

If your column has been already created due to binding with a recordset of BIT type, the type of the column will be text anyway. The solution I have found is to remove that column and replace it with a DataGridViewCheckBoxColumn having the same binding data.
DataGridViewColumn oldCol = dgViewCategory.Columns["mycolumn"];
int chkIdx = oldCol.Index;
DataGridViewCheckBoxColumn chkCol = new DataGridViewCheckBoxColumn();
chkCol.HeaderText = oldCol.HeaderText;
chkCol.FalseValue = "False";
chkCol.TrueValue = "True";
chkCol.DataPropertyName = oldCol.DataPropertyName;
chkCol.Name = oldCol.Name;
dgViewCategory.Columns.RemoveAt(chkIdx);
dgViewCategory.Columns.Insert(chkIdx, chkCol);

Related

DataGridView C# windows application(First row not selecting which is checkbox if mouse click on column Header)

Can please any one help me on this. I have developed a c# windows application which has DataGridView first column has checkboxes. if I click on first column header it selects all the row level check boxes except the first row. For selecting all row level check boxes I have an event of dataGridView1_ColumnHeaderMouseClick and the code is:
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
column.SortMode = DataGridViewColumnSortMode.NotSortable;
}
if (e.ColumnIndex == 0)
{
if (chek == 0)
{
try
{
for (int i = 0; i < dataGridView1.RowCount; i++)
{
string paymentValue = dataGridView1.Rows[i].Cells[18].Value.ToString();
string incmngp = dataGridView1.Rows[i].Cells[20].Value.ToString();
if (paymentValue == "N" && incmngp =="")
{
dataGridView1.Rows[i].Cells[0].Value = 1;
chek = 1;
}
}
if (chek == 1)
{
btn_update.Text = "Update";
}
}
catch (Exception ) { }
}
else if(chek==1)
{
try
{
for (int i = 0; i < dataGridView1.RowCount; i++)
{
dataGridView1.Rows[i].Cells[0].Value = 0;
chek = 0;
}
if (chek == 0)
{
btn_update.Text = "OK";
}
}
catch (Exception) { }
}
}
Note: chek is the variable declared on initialize stage
Set your Selection mode property of data grid view to ColumnHeaderSelect
and make sure all your 'Text' columns have SortMode set to NotSortable
UPDATE 2
In which case, Undo everything I ever told before and do that like this
Before you are assigning any DataTable to dataGridView1.
da.Fill(dt);
dataGridView1.DataSource = dt.DefaultView;
dataGridView1.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
foreach(DataGridViewColumn dc in dataGridView1.Columns)
{
dc.SortMode = DataGridViewColumnSortMode.NotSortable;
}
dataGridView1.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
UPDATE 3
Add an event handler for your dataGridView1's ColumnHeaderMouseClick Event
like below
Add the below code (Generic code if you want to use the same functionality for any column of check boxes)
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
//Enter your own column index here
if(e.ColumnIndex == 0)
foreach(DataGridViewRow row in dataGridView1.Rows)
foreach (DataGridViewCell cell in row.Cells)
{
//Check if the cell type is of a CheckBoxCell
if (cell.GetType() == typeof(DataGridViewCheckBoxCell))
{
DataGridViewCheckBoxCell c = (DataGridViewCheckBoxCell)cell;
c.TrueValue = "T";
c.FalseValue = "F";
if (c.Value == c.FalseValue|| c.Value == null )
c.Value = c.TrueValue;
else
c.Value = c.FalseValue;
}
}
dataGridView1.RefreshEdit();
}
This is a very bizarre bug in Winforms. The problem more generally applies not to the first row, but to the first selected cell in any row of DataGridViewCheckBoxCell(s). You can select the CheckBox cell by clicking on the check box, or select the cell outside the check box, the behavior is the same. If you select 3 check boxes in the middle of your grid, the first of those three will freeze and not update properly. If you try to clear the selection in code, with a dataGridView1.ClearSelection() method call, it still does not work.
The correct answer is to call datagridview1.RefreshEdit() right after you change the checkbox data. You can't just call it after all changes are made. It must be made for each change in the CheckBox value.
foreach (DataGridViewRow row in Results.Rows)
{
var ck = (DataGridViewCheckBoxCell) row.Cells["check"];
ck.Value = ck.TrueValue;
Results.RefreshEdit();
}

c# windows form Filtering using RadioButton

Can any one tell me how to filter the Datagridview based on selected radio button, i have attached a screenshot of the form I created, need to filter based on deposit and withdrawal. I have taken TransactionType as enum.
Loop through the rows in your DGV and check if the first cell value = value (Deposit/Withdrawal/Both depending on which RadioButton is checked), then set
DataGridView1.Rows[rowIndex].Visible = false;
You can change your DataSource according the selected radio button.
BindingSource bs = new BindingSource();
grid.DataSource = bs;
By changing your radiobutton selection
bs.DataSource = q;
bs.ResetBindings(false);
for q use:
var q = Transactions
var q = Transactions.Where(t=>t.TransactionType==Deposit)
var q = Transactions.Where(t=>t.TransactionType==Withdrawal)
A code that does what you want would look like this: (probably not the right variable names)
Check value which radio button is checked
according to which one is checked, read column"transactionType" of each row,
render visible or not the rows you want.
Foreach(DataGridViewRow row in DataGridView.Rows)
{
if(radioButtonDeposit.isChecked())
{
if(row["TransactionType"].Value == Enum.Deposit)
{
row.Visible = true;
}
else
{
row.Visible = false;
}
}
else if(radioButtonWithdrawal.isChecked())
{
if(row["TransactionType"].Value == Enum.Withdrawal)
{
row.Visible = true;
}
else
{
row.Visible = false;
}
}
else
row.Visible = true;
}

DataGridView with a checkbox with default value checked

I have a dataGridView in a Winform, I added to the datagrid a column with a checkbox using a code I saw here :
DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
{
column.HeaderText = "Export";
column.Name = "Export";
column.AutoSizeMode =
DataGridViewAutoSizeColumnMode.DisplayedCells;
column.FlatStyle = FlatStyle.Standard;
column.CellTemplate = new DataGridViewCheckBoxCell(false);
column.CellTemplate.Style.BackColor = Color.White;
}
gStudyTable.Columns.Insert(0, column);
this works but I want the checkBox to be checked as a default saw I added :
foreach (DataGridViewRow row in gStudyTable.Rows)
{
row.Cells[0].Value = true;
}
but the checkbox col is still unchecked. I'm using a collection as my data source and I change the value of the col after I added the data source.
I think there is no way of setting the checked value on column declaration.
You will have to iterate through the rows checking it after datasource is set (for example in DataBindingComplete event):
for (int i = 0; i < dataGridView1.Rows.Count -1; i++)
{
dataGridView1.Rows[i].Cells[0].Value = true;
}
With your column name:
for (int i = 0; i < dataGridView1.Rows.Count -1; i++)
{
dataGridView1.Rows[i].Cells["Export"].Value = true;
}
Try to do it like this:
foreach (DataGridViewRow row in dgv.Rows)
{
row.Cells[CheckBoxColumn.Name].Value = true;
}
Make sure your DataGridView is shown when you set the value of your DataGridViewCheckBoxCells: I had mine in the second tab of a TabControl and the cells were always unchecked after initialization. To solve this, I had to move cell initialization to TabControl's SelectedIndexChanged event.
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.tabControl1.SelectedIndex == 1)
{
foreach (DataGridViewRow row in this.myGridView.Rows)
{
((DataGridViewCheckBoxCell)row.Cells[0]).Value = true;
}
}
}
You can use datatable and create columns in datagridview and then add rows, provided first column value as 'True' or 'False' for each row.
try this
if ((bool)this.dataGridView2.Rows[i].Cells[0].FormattedValue == true)
During or after load the value in a grid, for check the value in grid use this code and set the properties of grid column
foreach (DataGridViewRow row in dataGridView.Rows)
{
row.Cells[0].Value = 1;
}
Have a look at the properties within your .xsd file for the table format:
Then make sure you set the default value to something sensible:
It will then automatically set the default value to the binding source.
An easy way is to use the property NewRowIndex as shown below:
dvgInvoiceItems.Rows[dvgInvoiceItems.NewRowIndex-1].Cells[5].Value = true;
dvgInvoiceItems.Rows[dvgInvoiceItems.NewRowIndex-1].Cells[6].Value = true;

Check All Checkbox items on DataGridView

Here's the scenario.
I have checkbox(Name:"Check All" ID:chkItems) and datagridview. And when I click on this checkbox, all checkboxes on the datagridview will also be checked.
I've also added the checkbox column on the grid.
DataGridViewCheckBoxColumn CheckboxColumn = new DataGridViewCheckBoxColumn();
CheckBox chk = new CheckBox();
CheckboxColumn.Width = 20;
GridView1.Columns.Add(CheckboxColumn);
Here is the code behind of the checkbox. There is a problem on the row.Cell
private void chkItems_CheckedChanged(object sender, EventArgs e)
{
foreach (DataGridViewRow row in GridView1.Rows)
{
DataGridViewCheckBoxCell chk = e.row.Cells(0);
if (chk.Selected == false)
{
row.Cells(0).Value = true;
}
}
}
DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell) row.Cells[0];
instead of
DataGridViewCheckBoxCell chk = e.row.Cell(0);
*EDIT:*I think you really want to do this:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell) row.Cells[0];
chk.Value = !(chk.Value == null ? false : (bool) chk.Value); //because chk.Value is initialy null
}
private void setCheckBoxInDataGrid(DataGridView dgv, int pos, bool isChecked)
{
for (int i = 0; i < dgv.RowCount; i++)
{
dgv.Rows[i].DataGridView[pos, i].Value = isChecked;
}
}
This is how I did it
Try this one
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
row.Cells[0].Value = row.Cells[0].Value == false ? true : false;
}
If you are okay with providing a default state to the checkboxes of datagridview on your own i.e either True or False[Do not assign a null state] state(Reason for doing this would be explained in the latter).
Which could be done by the following code,(type in this code when you search for results to be viewed in DataGridView)
dgv is the object of the DataGridView that you are using.
for (int i = 0; i < dgv.RowCount - 1; i++)
{
dgv.Rows[i].DataGridView[0, i].Value = true;
}
Where DataGridView[0, i] indicates 0th column ith row
The Reason for doing this is,On load the checkbox is by default in a null state. The code isn't comparing for null state(Creating a object null reference exception). So, once when u assign it a state either a false or true . It can never undergo into null state.
Type in the following code inside the button_click_event using which you are going to check
for (int i = 0; i < dgv.RowCount-1; i++)
{
if (dgv.Rows[i].Cells[0].Value.ToString() != "")
{
dgv.Rows[i].Cells[0].Value = false;
}
else
{
dgv.Rows[i].Cells[0].Value = true;
}
}
It Worked for me, I hope it does for you.
I tried to select all checkbox or select it mutuality and calculate some value...so wrote this code that's maybe helpful.
foreach (DataGridViewRow item in DGDoc.Rows)
{
if (item.Cells[0].Value == null)
item.Cells[0].Value = "True";
if (bool.Parse(item.Cells[0].Value.ToString()))
{
item.DefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(241, 215, 215);
strIDs += "," + item.Cells[1].Value.ToString();
intSumPrice += Int64.Parse(item.Cells[4].Value.ToString());
intSumTax += Int64.Parse(item.Cells[5].Value.ToString());
intSumPay += Int64.Parse(item.Cells[6].Value.ToString());
}
else
{
item.DefaultCellStyle.BackColor = System.Drawing.Color.Empty;
}
}
DGDoc.EndEdit();
1- Create new button.
2- You can use the following code when click checkAll button
3- when click the button it will check all checkboxes in datagridview and when click again it will uncheck all boxes.
private void btncheckall_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dgvResult.Rows)
{
row.Cells[0].Value = row.Cells[0].Value == null ? false : !(bool)row.Cells[0].Value;
}
}
Note: in some cases you have to click in datagridview first then click the button.
You can check all cells like this:
private void CheckAllCheckboxItemsOnDataGridView(int columnIndex)
{
foreach (DataGridViewRow row in dgFiles.Rows)
{
DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)row.Cells[columnIndex];
cell.Value = !(cell.Value == null ? false : (bool)cell.Value);
}
}
You can use method in CheckedChanged event like this:
private void chkItems_CheckedChanged(object sender, EventArgs e)
{
CheckAllCheckboxItemsOnDataGridView(columnIndex: 0);
}
This is my version, which allows a more natural behavior I'd say; if one of the checkboxes is ticked, all checkboxes are ticked as well when selecting all.
How it'll be usefull to you :)
private void BtnSelectAll_Click(object sender, EventArgs e)
{
List<Boolean> chkList = new List<Boolean>();
bool ticked = false;
foreach (DataGridViewRow row in dataGrid.Rows)
{
DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)row.Cells[0];
chkList.Add((bool)chk.Value);
}
if (!chkList.Contains(true))
{
ticked = true;
}
else if (!chkList.Contains(false))
{
ticked = false;
} else
{
ticked = true;
}
foreach (DataGridViewRow row in dataGrid.Rows)
{
DataGridViewCheckBoxCell chk = (DataGridViewCheckBoxCell)row.Cells[0];
chk.Value = ticked;
}
}

DataGridViewImageColumn don't display the value - why?

I want to display some images in my dataGridView, so I created DataGridViewImageColumn with default image (Properties.Resources.test), added it to dataGridView and tried to insert some values to cells. Unfortunately it didn't change the display. What Am I doing wrong?
var q = from a in _dc.GetTable<Map>() select a;
View.dataGridView1.DataSource = q;
View.dataGridView1.Columns[3].Visible = false;
var imageColumn = new DataGridViewImageColumn
{
Image = Properties.Resources.test,
ImageLayout = DataGridViewImageCellLayout.Stretch,
Name = "Map",
HeaderText = #"map"
};
View.dataGridView1.Columns.Add(imageColumn);
var i = 0;
foreach (var map in q)
{
View.dataGridView1.Rows[i].Cells[8].Value = ByteArrayToImage(map.map1.ToArray());
i++;
}
As explained in the question in the comment you need to use the CellFormatting event like so:
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].Name == "StatusImage")
{
// Your code would go here - below is just the code I used to test
e.Value = Image.FromFile(#"C:\Pictures\TestImage.jpg");
}
}
So set e.Value rather than cell.Value and assign the image.
you can do like this...
for(int i = 0; i < dataGridView1.Columns.Count; i ++)
if(dataGridView1.Columns[i] is DataGridViewImageColumn) {
((DataGridViewImageColumn)dataGridView1.Columns[i]).ImageLayout = DataGridViewImageCellLayout.Stretch;
break;
}

Categories