DataGridViewCheckBoxColumn get state - c#

I've got a DataGridView dgView which I populate with several different Forms, e.g. a DataGridViewCheckBoxColumn. To handle events, I added
private void InitializeComponent()
{
...
this.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgView_CellClick);
...
}
The implementation looks like:
private void dgView_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (Columns[e.ColumnIndex].Name == "Name of CheckBoxColumn") // this is valid and returns true
{
Console.WriteLine("Handle single click!");
// How to get the state of the CheckBoxColumn now ??
}
}
This is where I am stuck. I already tried different approaches but with no success at all:
DataGridViewCheckBoxColumn cbCol = Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewCheckBoxColumn; // does not work
DataGridViewCheckBoxColumn cbCol = (DataGridViewCheckBoxColumn)sender; // nor this
if (bool.TryParse(Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue.ToString(), out isBool)) // nor this
{ ... }
Could anybody point out how to retrieve the State of this CheckBoxColumn please? Besides, do any other events exist do address the CheckBoxColumn directly? (such as "ValueChanged" or something)
Update:
The approach
DataGridViewCell dgvCell = Rows[e.RowIndex].Cells[e.ColumnIndex];
Console.WriteLine(dgvCell.Value);
at least returns true / false at the point of time before the value gets changed (or not) by clicking the cell. But all in all there should be a solution to address the CheckBoxColumn directly.
Solution:
Sometimes an answer is too obvious to see. The problem I was facing was that the event "CellClick" triggered when clicking on the cell as well as clicking on the checkbox. The proper handling therefore is to use a "CellValueChanged" event instead:
private void InitializeComponent()
{
...
this.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgView_CellValueChanged);
...
}
To determine the value of the checkbox I use the same way as stated above:
if (e.ColumnIndex != -1 && Columns[e.ColumnIndex].Name == "Name of Checkbox")
{
bool cbVal = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
}

One way to manipulate UI components is by use of Data Bindings. See for example:
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Online Order?" IsThreeState="True" Binding="{Binding OnlineOrderFlag}" />
</DataGrid.Columns>
This links explains DataGrid usage in detail.
But anyways, have you tried doing QuickWatch the sender to see what is the type of it?

you could cast the cell to a checkbox and check if it's checked there...
CheckBox chkb = (CheckBox)Rows[e.RowIndex].FindControl("NameOfYourControl");
then just do a check against chkb
if (chkb.Checked == true)
{
//do stuff here...
}

You can simply cast the value of the cell to bool
//check if it's the good column
bool result = Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
edit : I'm probably missing something in your question but if you update/add detail I will have a look
edit 2 : After the comment,
If you want to do it in the cellClick just reverse the value it give you.
bool result = !Rows[e.RowIndex].Cells[e.ColumnIndex].Value;

The proper handling is to use a "CellValueChanged" event:
private void InitializeComponent()
{
...
this.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgView_CellValueChanged);
...
}
To determine the value of the checkbox:
private void dgView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex != -1 && Columns[e.ColumnIndex].Name == "Name of Checkbox")
{
Console.WriteLine( Rows[e.RowIndex].Cells[e.ColumnIndex].Value );
}
}

Related

Infragistics Get Name-Property trough Cell Click c#

I have created more than 5 GRID for which there are a few column that are empty/zero. These are numbered as example 1,2,3...
I have already implemented that I can select and deselect single cells for this columns.
Now my question is (and I am still very inexperienced with Infragistics)
How do I get the Name Property of my grid just by clicking on it?
Some parameters I could read out like the cells.index or the rows.index, but I want to know for another method the exact Name Property in which just the cell was clicked.
Via the event handler I let all my grids into the cells click method
private void GRD_LIST_Grid_ClickCell(object sender, Infragistics.Win.UltraWinGrid.ClickCellEventArgs e)
{
if (e.Cell.Column.ToString().Contains("BAHN") && e.Cell.Tag == "1") //1-5 Column have the name "BAHN", the Tag is for an flag if the cell is clicked before
{
e.Cell.Selected = false;
e.Cell.Tag = null;
SetPrio(e.Cell.Row.Index, e.Cell.Column.Index);
}
else if (e.Cell.Column.ToString().Contains("BAHN") && e.Cell.Tag == null)
{
SetPrio(e.Cell.Row.Index, e.Cell.Column.Index);
e.Cell.Tag = "1";
}
//when the cell is click show the cell in green
if (e.Cell.Tag == "1")
{
e.Cell.Row.Cells[e.Cell.Column.ToString()].Appearance.BackColor = System.Drawing.Color.Green;
}
else if (e.Cell.Tag == null)
{
e.Cell.Row.Cells[e.Cell.Column.ToString()].Appearance.BackColor = System.Drawing.Color.FromArgb(234,244,243);
}
ClearSelectedRow(); //a Method where i set all grids in an array and clear all rows because i dont know which grid i am
}
When the ClickCell event occurs the first parameter of the event handler is sender and in this case it's the Infragistics.Win.UltraWinGrid.UltraGrid source. Therefore, it is possible to get the grid name like in code below:
private void GRD_LIST_Grid_ClickCell(object sender, Infragistics.Win.UltraWinGrid.ClickCellEventArgs e)
{
if (sender is Infragistics.Win.UltraWinGrid.UltraGrid ugrid)
{
System.Diagnostics.Debug.WriteLine($"The ClickCell event is raised by '{ugrid.Name}'");
}
}

How can I get the value of two specific cells in the DataGridView and store them in variables

How can I get the variables that are in two specific columns in DataGridView, for example I want the Id that is in the first column and the name that is on the third. How can I do that? I'm trying the RowEnter event but when I searched online I can't find anything that I can follow up. Thanks guys.
private void dataGridViewDocumentos_RowEnter(object sender, DataGridViewCellEventArgs e)
{
DataGridViewRow dgvr = dataGridViewDocumentos.SelectedRows[0];
dgvr.Cells[];
foreach (DataGridViewRow Datarow in contentTable_dgvr.Rows)
{
if (dgvr.Value != null && Datarow.Cells[1].Value != null)
{
int contentJobId = 0;
contentJobId = Datarow.Cells[0].Value.ToString();
contentValue2 = Datarow.Cells[1].Value.ToString();
MessageBox.Show(contentValue1);
MessageBox.Show(contentValue2);
}
}
}
This is what I have right now, as you guys can see I'm missing a lot of things, I'm not familiar with this so if you guys can point what I need to do I'd appreciate it.
Well, the 1st question is, is this on a button click outside the grid? Or is this in response to an specific event that has happens? The reason why I ask that is because in your code sample you are using the RowEnter event which will fire everytime the row recieves input. I am not sure if that is what you want ot not.
Anyway, I mean you are pretty much there with your code sample. If you want to get the selected 1st and 3rd column for the selected row you could use this code.
private void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e)
{
var activeCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
var fistColumnCell = dataGridView1.Rows[e.RowIndex].Cells[0];
var thirdColumnCell = dataGridView1.Rows[e.RowIndex].Cells[2];
MessageBox.Show(fistColumnCell.Value.ToString());
MessageBox.Show(thirdColumnCell.Value.ToString());
}
Notice that the 2nd paramater of the function named DataGridViewCellEventArgs has properties for ColumnIndex and RowIndex which you can use to get the currently selected row.
However, if this code should fire in response to a user double clicking a cell you could use the CellDoubleClick event
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
var fistColumnCell = dataGridView1.Rows[e.RowIndex].Cells[0];
var thirdColumnCell = dataGridView1.Rows[e.RowIndex].Cells[2];
MessageBox.Show(fistColumnCell.Value.ToString());
MessageBox.Show(thirdColumnCell.Value.ToString());
}

How to deny rows deletion based on class property value? C# WPF

I want to deny deletion of a row in case some there is a property with specific value, for example if product type is Steel I would like to deny user from deleting that row..
I'm setting source to my datagrid like this:
dataGridSourceList = new ObservableCollection<DatabaseItems>(TempController.Instance.SelectItemsByUserId(Globals.CurrentUser.Id));
dtgMainItems.ItemsSource = dataGridSourceList;
I saw there is a property CanUserDeleteRows
And I've added this to definition of my datagrid in xaml but I'm not sure how to apply this properly..
CanUserDeleteRows="{Binding ElementName=dtgMainItems, Path=SelectedItem.IsDeleteEnabled}"
Any kind of help would be awesome
Thanks
You could handle the CommandManager.PreviewCanExecute attached event:
private void OnPreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (e.Command == DataGrid.DeleteCommand)
{
DatabaseItems selectedItem = dtgMainItems.SelectedItem as DatabaseItems;
if (selectedItem != null && !selectedItem.IsDeleteEnabled)
e.Handled = true;
}
}
XAML:
<DataGrid x:Name="dtgMainItems" CommandManager.PreviewCanExecute="Grid_PreviewCanExecute" />

How to activate combobox on first click (Datagridview)

In winforms, you need to click the combobox twice to properly activate it - the first time to focus it, the second time to actually get the dropdown list.
How do I change this behavior so that it activates on the very first click?
This is for DATAGRIDVIEW combobox.
I realize this is an old question, but I figured I would give my solution to anyone out there that may need to be able to do this.
While I couldn't find any answers to do exactly this... I did find an answer to a different question that helped me.
This is my solution:
private void datagridview_CellEnter(object sender, DataGridViewCellEventArgs e)
{
bool validClick = (e.RowIndex != -1 && e.ColumnIndex != -1); //Make sure the clicked row/column is valid.
var datagridview = sender as DataGridView;
// Check to make sure the cell clicked is the cell containing the combobox
if(datagridview.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn && validClick)
{
datagridview.BeginEdit(true);
((ComboBox)datagridview.EditingControl).DroppedDown = true;
}
}
private void datagridview_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
datagridview.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
The above code must be tied into the CellEnter event of the datagridview.
I hope this helps!
edit: Added a column index check to prevent crashing when the entire row is selected.
Thanks, Up All Night for the above edit
edit2: Code is now to be tied to the CellEnter rather than the CellClick event.
Thanks, HaraldDutch for the above edit
edit3: Any changes will committed immediately, this will save you from clicking in another cell in order to update the current combobox cell.
Set the following on your DataGridView:
EditMode = EditOnEnter
This is probably the easiest solution and has been the workaround for many users here on SO when this question gets asked.
EDIT :
Per here do the following:
Set the Editmode:
EditMode = EditOnKeystrokeOrF2
Modify the EditingControlShowing event on the datagridview:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox ctl = e.Control as ComboBox;
ctl.Enter -= new EventHandler(ctl_Enter);
ctl.Enter += new EventHandler(ctl_Enter);
}
void ctl_Enter(object sender, EventArgs e)
{
(sender as ComboBox).DroppedDown = true;
}
This will get you your desired results. Let me know if that doesn't do it.
I changed only the EditMode property of the datagridview to EditOnEnter and it's working perfectly.
EditMode = EditOnEnter
If you set the entire grid to EditOnEnter, you can get some pretty funky activity when you are on a text column. Here's my solution, which should be self explanatory. If you did not know the column names, you could just check the cell type on mousemove.
Private Sub GridView_CellMouseMove(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles GridView.CellMouseMove
Select Case GridView.Columns(e.ColumnIndex).Name
Case "Ad_Edit", "Size_Caption", "Demo_Code"
GridView.EditMode = DataGridViewEditMode.EditOnEnter
Case Else
GridView.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
End Select
End Sub
Set the DropDownStyle property of your combo box to DropDownList...
Perhaps old.. But make sure to set ReadOnly property to false, else the cell wont enter editmode and therefore the EditingControl returns null and casting DroppedDown = true will cast a NullReferencException.

How do I execute code after a certain checkbox is selected

I have a datagridview with multiple checkboxes. When the Finished checkbox is checked I need to execute linq code to update a specific table. How do I find out if that specific check box is dirty and where do I write the code to pass the values I need to be passed to the table. Note that it is not the same table that the datagridview is based on.
Thanks.
EDIT:
private void propertyInformationDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)propertyInformationDataGridView.Rows[e.RowIndex].Cells[3];
DataGridViewRow row = propertyInformationDataGridView.Rows[e.RowIndex] as DataGridViewRow;
System.Data.DataRowView SelectedRowView;
newCityCollectionDataSet.PropertyInformationRow SelectedRow;
SelectedRowView = (System.Data.DataRowView)propertyInformationBindingSource.Current;
SelectedRow = (newCityCollectionDataSet.PropertyInformationRow)SelectedRowView.Row;
if (Convert.ToBoolean(checkCell.EditedFormattedValue) == true)
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var matchedCaseNumber = (from c in dc.GetTable<PropertyInformation>()
where c.CaseNumberKey == SelectedRow.CaseNumberKey
select c).SingleOrDefault();
reportsSent newReport = new reportsSent();
newReport.CaseNumberKey = SelectedRow.CaseNumberKey;
dc.reportsSents.InsertOnSubmit(newReport);
dc.SubmitChanges();
}
}
Do I need to endedit at some point is that the issue?
This is from some of my code, all you need to do is create a "CellContentClick" event for your datagridview.
The easiest way to do this is select the Datagridview, go to properties and click on the lightning bolt. Scroll down to "CellContentClick" and double click in the empty box. This will auto generate the method you need to paste the following code into.
Make sure you rename my instances of "CustomersDataGridView" to whatever yours is named as well, intellisense should highlight invalid code in red that you need to replace.
Also, the "9" you see in the checkCell declaration needs to be changed to the index of your "Finished" check-box. If it is in the 3rd cell from the left, put a 2 there instead of a 9, as the indexing is 0 based.
EDITTED to fix comments:
private void CustomersDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex.ToString() == "9")
{
DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)CustomersDataGridView.Rows[e.RowIndex].Cells[9];
DataGridViewRow row = CustomersDataGridView.Rows[e.RowIndex] as DataGridViewRow;
if (Convert.ToBoolean(checkCell.EditedFormattedValue) && CustomersDataGridView.IsCurrentCellDirty)
{
//Do Work here.
var z = row.Cells[0].Value; // Fill in the brackets with the column you want to fetch values from
//z in this case would be the value of whatever was in the first cell in the row of the checkbox I clicked
}
}
}
You can do it in the CheckedChanged-Event
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
// Do what you have to do...
}

Categories