Counting rows in datagridview using c# - c#

I used following code to count datagrid rows, but it works on button only. I want the total number of rows in a textbox, but it doesn't increment itself as the number of rows increase.
int numRows = dataGridView1.Rows.Count;
txtTotalItem.Text = numRows.ToString();

When you assign the number, the textbox will display only that number, it will not update.
You can use an event and assign the new number to the textbox.
dataGridView1.RowsAdded+=(s,a)=>OnRowNumberChanged;
private void OnRowNumberChanged()
{
txtTotalItem.Text = dataGridView1.Rows.Count.ToString();
}
Following Equalsk's answer, you need to have the event for removed rows as well. You can subscribe to both events with the same function since you need to just check the number.
dataGridView1.RowsRemoved+=(s,a)=>OnRowNumberChanged();

If I've understood your question correctly you want the TextBox value to change automatically when rows are added or removed because at the moment you have to press a button to refresh. Am I right?
If so just subscribe to the .RowsAdded and .RowsRemoved events and update the TextBox from there.
dataGridView1.RowsAdded += RowsAdded;
dataGridView1.RowsRemoved += RowsRemoved;
private void RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
txtTotalItem.Text = dataGridView1.Rows.Count.ToString();
}
private void RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
txtTotalItem.Text = dataGridView1.Rows.Count.ToString();
}

the datagridview will count the last empty row so make sure to
look for AllowUserToAddRows property of datagridview and set it to False.
Or add this to your code, in my case i used a label and i named it labelTotalResult, do this if you want to keep the property as true
labelTotalResult.Text = (dataGridView1.RowCount - 1).ToString();

Related

Datagridview winforms cells doesnt get updated unless focus back on the grid

I am working with winforms c# datagridview and ran into a bug that I m not sure how to resolve. I have a datagridview in which the datasource is a datatable. The datagridview contains editable text fields and cellvaluechanged event as well as button column which I respond to thru a cellclick event. Currently when I change the value in a cell , hit the enter key to leave the just updated cell and click the button. The cellclick event which acts as the button click runs a task (TPL) in which the continuewith of the tasks updates values in the datagridview and that works because all the values that needed to be changed gets changed. The issue is that when I change a text value and don't hit the enter key and just immediately click the button on the row. the ui doesn't get updated intill I click on the cells to see the new values. I have looked this up and found that if I set the
datagridview.Currentcell = datagridview.Rows[e.RowIndex].Cells[4]
to the cells that I want to see the new values to. The new values appear. I don't want run for each cell I was wondering if there is a better way in handling this issue?
This is the code:
private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Button on grid
if (e.ColumnIndex == 17)
{
string val1 = dgv.Rows[e.RowIndex].Cells[3].Value.ToString();
string val2 = dgv.Rows[e.RowIndex].Cells[5].Value.ToString();
Task.Factory.StartNew<Dictionary<string, Response>>(() => GenerateData(val1, val2)).ContinueWith(ant => {
int rowId = Convert.ToInt32(this.dgv.Rows[e.RowIndex].Cells[1].Value);
SetResponse(rowId, this.DataSet.DataTable, ant.Result);
// i have tried the code below and it fixes the issue but don't want to go this route
//for (int i = 5; i < 12; i++) dgv.CurrentCell = dgv.Rows[e.RowIndex].Cells[i];
}, TaskScheduler.FromCurrentSynchronizationContext());
}
}
}
private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 5)
{
string val1 = this.dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString().Trim();
if (!string.IsNullOrEmpty(val1))
{
//dgv.BeginEdit(false);
this.dgv.Rows[e.RowIndex].Cells[6].Value = DBNull.Value;
//dgv.EndEdit(DataGridViewDataErrorContexts.Commit);
}
}
}
By adding these two lines of code resolved the issue
this.dgv.EndEdit();
this.dgv.CurrentCell = null;

How to change datagrid cell value when user leaves cell

Can't find any way to do what i what.
I have a DataGridView named data1. All i want is to check if current cell is acceptable(not lower than -99) after we fill it. And if it is - change it to -99. Similar if i set minimum to a textbox and change its value if it's not correct.
Here is the code:
private void data1_CellLeave(object sender, DataGridViewCellEventArgs e)
{
if (Convert.ToInt32(((DataGridView)sender).CurrentCell.Value) < -99)
{
((DataGridView)sender).CurrentCell.Value = -99;
}
}
This code does not work. And no errors appeared.
This code works as you want it to:
private void data1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
DataGridViewTextBoxCell cell = (DataGridViewTextBoxCell)data1.Rows[e.RowIndex].Cells[e.ColumnIndex];
if (Convert.ToInt32(cell.Value) <= -99)
cell.Value = -99;
}
Cellleave Event gets previous value of the cell after you have changed it to a different one and left the cell. And CellEndEdit Event gets the last value. The code works the same also in CellValidated Event.
I think what you are looking for is DataGridView.CellValidating this event fires when the user is leaving the current cell but before CellLeave fires or bound data gets pushed to the datasource. This allows you to: check the value the user entered, prevent the user from leaving the cell, change the value the user entered, set an error indicator on the cell.

Display Member is not display at the first time event fired in RepositoryLookupEdit in Winforms Gridview Devexpress?

I used RepositoryLookupEdit in my 1st Column of Gridview. Using EditValueChanged Event remaining columns fill automatically, till now every thing is working fine. Then I call one Function inside RepositoryLookupEdit, After that very first time this EditValueChanged event fired my Display Member is not shown, it simply shows Null value that i given. Next time if I reselect same column it working fine. What was wrong here ?
private void repositoryItemGridLookUpEdit1_EditValueChanged(object sender, EventArgs e)
{
GridLookUpEdit LookupEdit = sender as GridLookUpEdit;
DataRowView SelectedDataRow = (DataRowView)LookupEdit.GetSelectedDataRow();
gridView1.SetFocusedRowCellValue("Description", SelectedDataRow["ProductDescription"]);
gridView1.SetFocusedRowCellValue("UoM", SelectedDataRow["UnitofMeasure"]);
gridView1.SetFocusedRowCellValue("Quantity", SelectedDataRow["DefaultQuantity"]); //UnitPrice
gridView1.SetFocusedRowCellValue("UnitPrice", SelectedDataRow["MRPPrice"]);
gridView1.SetFocusedRowCellValue("DiscountPercentage", SelectedDataRow["Discount"]);
gridView1.SetFocusedRowCellValue("DiscountAmount", SelectedDataRow["DiscountAmount"]);
gridView1.SetFocusedRowCellValue("TaxInPercentage", SelectedDataRow["Taxid1"]);
Taxamountcalc(); // function to calculate taxamount
rowcount = gridView1.RowCount;
}
In this above code if i remove or comment "Taxamountcalc()" then my display member display properly if i enables this function then it show "NullText" only.
private void Taxamountcalc()
{
if (barCheckItem1.Checked)
{
TaxAmount.UnboundType = DevExpress.Data.UnboundColumnType.Decimal;
TaxAmount.UnboundExpression = "Round([UnitTotal] * ([TaxInPercentage] / 100), 2)";
}
else if (!(barCheckItem1.Checked))
{
TaxAmount.UnboundType = DevExpress.Data.UnboundColumnType.Decimal;
TaxAmount.UnboundExpression = "Round(([UnitPrice] * ([TaxInPercentage] / 100)) * [Quantity], 2)";
}
}
Don't call any function from RepositoryLookupdit EditValueChanged Event. If we call any function from EditValueChanged Event, for the First time selecting any values from lookupedit display Member is not displays it simply shows nulltext.
private void repositoryItemGridLookUpEdit1_EditValueChanged(object sender, EventArgs e)
{
GridLookUpEdit LookupEdit = sender as GridLookUpEdit;
DataRowView SelectedDataRow = (DataRowView)LookupEdit.GetSelectedDataRow();
gridView1.SetFocusedRowCellValue("Description", SelectedDataRow["ProductDescription"]);
gridView1.SetFocusedRowCellValue("UoM", SelectedDataRow["UnitofMeasure"]);
gridView1.SetFocusedRowCellValue("Quantity", SelectedDataRow["DefaultQuantity"]); //UnitPrice
gridView1.SetFocusedRowCellValue("UnitPrice", SelectedDataRow["MRPPrice"]);
gridView1.SetFocusedRowCellValue("DiscountPercentage", SelectedDataRow["Discount"]);
gridView1.SetFocusedRowCellValue("DiscountAmount", SelectedDataRow["DiscountAmount"]);
gridView1.SetFocusedRowCellValue("TaxInPercentage", SelectedDataRow["Taxid1"]);
// Taxamountcalc();
// rowcount = gridView1.RowCount;
}
Now it is working properly

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 to check whether gridview's row is selected or not in c#.net windows application

I want to know how to check whether a gridview's row got selected or not.
I am working on windows application.
I want to put a if condition ie if a particular row gets selected then fill the textbox with the correspoding cell value.
I am just not getting the way how to give the condition in the if clause.
Handle the DataGridView.SelectionChanged event. Use the DataGridView.SelectedRows property to get the selected rows collection.
private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
// Update the text of TextBox controls.
textBox1.Text = dataGridView.SelectedRows[0].Cells[1].Value.ToString();
textBox2.Text = dataGridView.SelectedRows[0].Cells[2].Value.ToString();
....
}
Check DataGridViewRow.Selected property.
if (dataGridView.Rows[rowIndex].Selected)
{
// Do something ..
}
Check the selected property of DataGridViewRow, it returns true for selected else false.
bool isSelected = dataGridView1.Rows[e.RowIndex].Selected;
You can subscribe to the SelectionChanged event of the control and iterate through each selected row if multi-selection is enabled or just the first one if single-row selection only.
private void MyGridView_SelectionChanged(object sender, EventArgs e)
{
for (int i = 0; i < MyGridView.SelectedRows.Count; i++)
{
MyTextBox.Text = MyGridView.SelectedRows[i].Cells[0].Value.ToString(); //assuming column 0 is the cell you're looking for
// do your other stuff
}
}
More information can be found on the SelectedRows property.

Categories