c# .net datagridview SelectionChanged - c#

I'm racking my head over something that should be pretty simple to do. Its been a day now so I finally give up and I will ask the question. How can I actually trigger the selectionChanged event on the datagridview in .net?
I would basically like to grab the row values when the user double-clicks/ or single clicks any where on a row. but I cant for the life of me get this event to fire even tough I read here that this should be the even I need to use?
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
foreach (DataGridViewRow row in AddrGrid.SelectedRows)
{
string value1 = row.Cells[0].Value.ToString();
string value2 = row.Cells[1].Value.ToString();
//...
}
}
I have tried something similar to this but im hopeless I click on the datagrid cells or rows and this does not fire what I'm I missing?
when I click on a cell I get this event to fire.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
Addresses.aTyp = AddrGrid.Rows[AddrGrid.CurrentCell.RowIndex].Cells["Address Type"].Value.ToString();
Addresses.seq = AddrGrid.Rows[AddrGrid.CurrentCell.RowIndex].Cells["Sequence"].Value.ToString();
}
But I like to capture the double click or click on a row not just a cell.
Any help would be most appreciated.

private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
string value1 = row.Cells[0].Value.ToString();
string value2 = row.Cells[1].Value.ToString();
}
}

you can use this
private void AddrGrid_CellEnter(object sender, DataGridViewCellEventArgs e)
{
Addresses.aTyp = AddrGrid.Rows[AddrGrid.CurrentCell.RowIndex].Cells["Address Type"].Value.ToString();
Addresses.seq = AddrGrid.Rows[AddrGrid.CurrentCell.RowIndex].Cells["Sequence"].Value.ToString();
}

On your grid object lets call it 'foo'. You will do something like..
foo.SelectionChanged += dataGridView1_SelectionChanged
you will need to do that somewhere to wire the event up. I normally do it in the constructor for the form

Many answers relating to the selectionchanged event for a DataGridview use "DG1.SelectedRows(0)". This is fundementally wrong. There may be multiple rows selected and the first selected row may not be the newly selected row. Unless you want to parse over all of the selected rows each time, "DG1.Rows(DG1.CurrentCell.RowIndex)" should be used

Related

Automatic insertion of rows to DataGrid View without using a timer in Winforms

A row is to be automatically added in a datagridView of Winforms according to value changes in a text box.
A text box (textBox1) is used in the form to input the value. With the change in the value a row is to be inserted in the datagridview (dataGridView1)
I have used the following code for implementing the same,
private void timer1_Tick(object sender, EventArgs e)
{
int value;
value = Convert.ToInt32(textBox1.Text);
if(value == 2)
{
string[] row1 = {"Value is 2"};
dataGridView1.Rows.Add(row1);
}
}
The result I was expecting to get was a single row inserted in the dataGridView1.
I am getting the same row inserted a number of times since the code is running continuously inside the timer, timer1.
Can anyone help me with getting the expected result?
Can it be done without using a timer?
The usual approach would be to subscribe to the TextBox.TextChanged event:
//maybe in the form constructor
textBox1.TextChanged += HandleTextChanged;
Then you would need to implement a method HandleTextChanged somewhat like this (in the same class):
private void HandleTextChanged(object sender, EventArgs e)
{
if(int.TryParse(textBox1.Text, out var number))
{
if(number == 2)
{
string[] newRow = { "Value is 2" };
dataGridView1.Rows.Add(newRow);
}
}
}
For further information on events in WinForms, I propose you have a look at the documentation on learn.microsoft.com. Generally speaking WinForms is event-driven, so it's definitely useful to get used to the concept.
If you want to insert a new row according to the change in TextBox, you can use TextChanged event.
You delegate will be called each time the text is changed.
private void textbox_TextChanged(object sender, EventArgs e)
{
// place your code here for adding a row.
}
The textbox has a multitude of events, which you can inspect in the designer, by clicking it and selecting in the Properties window the yellow flash on the top.
if you want to add your textbox always as row when you finsihed editing the textbox,
use the apropiate event (Leave maybe) and add your row in there.
You could have your timer event tick once and then disable it:
private void timer1_Tick(object sender, EventArgs e)
{
int value;
value = Convert.ToInt32(textBox1.Text);
if(value == 2)
{
string[] row1 = {"Value is 2"};
dataGridView1.Rows.Add(row1);
}
timer1.Enabled = false; //<--disable timer1 once your job is done
}

be aware of insert delete and update data into gridview in c#

I have a grid view that has a column called Amount .I have a textbox that shows the sum of amount column in gridview ,but i need to be aware when items in gridview are inserted changed and deleted because i need to update the textbox
Has anyone handled such a scenario. I would like to know which datagrid event I should be using,
I am using windows form application
Best regards
You can make use of RowsRemoved, RowsAdded and CellValueChanged events.
Updated
You can use these assuming your user is only adding and deleting 1 row at a time. also added a method with a linq statement to sum up your amount and assign it to the textbox.
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex.Equals(dataGridView1.Columns["Amount"].Index))
{
UpdateTotal();
}
}
private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
UpdateTotal();
}
private void dataGridView1_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
{
UpdateTotal();
}
private void UpdateTotal()
{
textBox1.Text = (dataGridView1.Rows.Cast<DataGridViewRow>()
.Sum(t => Convert.ToInt32(t.Cells["Amount"].Value))).ToString();
}

C#: DataGridViewCheckBoxCell strange behaviour [duplicate]

I have a DataGridView that loads data from a DataTable, along with an unbound column of DataGridViewCheckBoxCells. The rows in the DataGridView are compared with a separate DataTable with values the user has saved, and if there is a match, the checkbox for that row should check.
Here is the code that compares the values and sets the checkbox value to 'true':
foreach (int j in selectedObjectives)
{
foreach (DataGridViewRow r in dgvObjectives.Rows)
{
if (j == Convert.ToInt32(r.Cells["ObjectiveID"].Value))
{
dgvObjectives.CurrentCell = r.Cells["Select"];
((DataGridViewCheckBoxCell)r.Cells["Select"]).Value = true;
//dgvObjectives.InvalidateCell(r.Cells["Select"]);
//dgvObjectives.EndEdit();
//dgvObjectives.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
if (Convert.ToInt32(r.Cells["ObjectiveID"].Value) == selectedIndex)
{
r.Selected = true;
}
}
}
When I call the method to perform this action during the form load private void WQMDrill_Load(object sender, EventArgs e), the values are set correctly, but the checkboxes do not check. However, when called after the form is finished loading, the code works perfectly. Unfortunately for me, I absolutely need for these to check during the load process.
I hope I was clear with my issue, any help on this matter would be greatly appreciated. As you can see, I have tried to invalidate the cell alone, as well as the entire DataGridView control. I also have
private void dgvObjectives_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (this.dgvObjectives.CurrentCell.ColumnIndex == 0)
{
this.dgvObjectives.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
That doesn't fire during this time. Thank you.
You can put your checkbox selection and update logic in the DataBindingComplete eventhandler, this fires after the FormLoad but before anything is displayed to the user.
I'm not certain that calling CommitEdit will actually fire the Paint on the cell. Try handling the CellMouseUp event and firing EndEdit if the column is a checkbox column.
private void dgvObjectives_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (dgvObjectives.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn)
{
dgvObjectives.EndEdit();
}
}
I had the same problem, and tried a lot of different ways to deal with it, most failed, except when I tried this.BeginInvoke(new CDelegate()).

DataGridViewCheckBoxCell how to show checked when set during form load

I have a DataGridView that loads data from a DataTable, along with an unbound column of DataGridViewCheckBoxCells. The rows in the DataGridView are compared with a separate DataTable with values the user has saved, and if there is a match, the checkbox for that row should check.
Here is the code that compares the values and sets the checkbox value to 'true':
foreach (int j in selectedObjectives)
{
foreach (DataGridViewRow r in dgvObjectives.Rows)
{
if (j == Convert.ToInt32(r.Cells["ObjectiveID"].Value))
{
dgvObjectives.CurrentCell = r.Cells["Select"];
((DataGridViewCheckBoxCell)r.Cells["Select"]).Value = true;
//dgvObjectives.InvalidateCell(r.Cells["Select"]);
//dgvObjectives.EndEdit();
//dgvObjectives.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
if (Convert.ToInt32(r.Cells["ObjectiveID"].Value) == selectedIndex)
{
r.Selected = true;
}
}
}
When I call the method to perform this action during the form load private void WQMDrill_Load(object sender, EventArgs e), the values are set correctly, but the checkboxes do not check. However, when called after the form is finished loading, the code works perfectly. Unfortunately for me, I absolutely need for these to check during the load process.
I hope I was clear with my issue, any help on this matter would be greatly appreciated. As you can see, I have tried to invalidate the cell alone, as well as the entire DataGridView control. I also have
private void dgvObjectives_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (this.dgvObjectives.CurrentCell.ColumnIndex == 0)
{
this.dgvObjectives.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
That doesn't fire during this time. Thank you.
You can put your checkbox selection and update logic in the DataBindingComplete eventhandler, this fires after the FormLoad but before anything is displayed to the user.
I'm not certain that calling CommitEdit will actually fire the Paint on the cell. Try handling the CellMouseUp event and firing EndEdit if the column is a checkbox column.
private void dgvObjectives_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (dgvObjectives.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn)
{
dgvObjectives.EndEdit();
}
}
I had the same problem, and tried a lot of different ways to deal with it, most failed, except when I tried this.BeginInvoke(new CDelegate()).

DataGridView capturing user row selection

I am having trouble handling the selections in DataGridView.
My grid view contains an amount column. There is a textbox on the form which should display the total amount of the selected grid view rows. Hence I need to capture events when the user selects/ deselects the gridview rows and calculate (add/ subtract) the amount accordingly. I have found two methods of doing it:
Using the RowEnter and RowLeave events.
These work fine when user selects/ deselects a single row. However, when the user is selecting multiple rows at one go, the event gets fired only for the last row. Hence, from my total amount only the amount in the last row gets added/ subtracted. Thus making my result erroneous.
Using the RowStateChanged event.
This works for multiple rows. However, the event gets fired event if the user scrolls through the datagrid.
Has anyone handled such a scenario. I would like to know which datagrid event I should be using, so that my code executes only when user selects/ deselects rows including multiple rows.
Found the solution. I can use RowStateChanged and run my code only if StateChanged for the row is Selected...
private void dgridv_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
{
// For any other operation except, StateChanged, do nothing
if (e.StateChanged != DataGridViewElementStates.Selected) return;
// Calculate amount code goes here
}
I use SelectionChanged event or CellValueChanged event:
dtGrid.SelectionChanged += DataGridView_SelectionChanged;
this.dtGrid.DataSource = GetListOfEntities;
dtGrid.CellValueChanged += DataGridView_CellValueChanged;
private void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
DataGridViewRow row = dtGrid.Rows[e.RowIndex];
SetRowProperties(row);
}
private void DataGridView_SelectionChanged(object sender, EventArgs e)
{
var rowsCount = dtGrid.SelectedRows.Count;
if (rowsCount == 0 || rowsCount > 1) return;
var row = dtGrid.SelectedRows[0];
if (row == null) return;
ResolveActionsForRow(row);
}
I think you can consider the SelectionChanged event:
private void DataGridView1_SelectionChanged(object sender, EventArgs e) {
textbox1.Text = DataGridView1.SelectedRows.Count.ToString();
}
You can use SelectionChanged event and retrieve the row index of the selected cell(s):
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.SelectedCells.Count > 0)
Do_Something_With_It(dataGridView1.SelectedCells[0].RowIndex);
}
You can simply capture this in following way, but it is restricted to single row selection only:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("Selected row is=" + e.RowIndex);
// you can perform (any operation) delete action on selected row like
dataGridView1.Rows.RemoveAt(e.RowIndex);
dataGridView1.Refresh();
}
You can use your first method (row enter row leave) along with the SelectedRows property. Meaning, when you detect those events, and you need to calculate, instead of using the row from the event args, loop through the SelectedRows and get your total.

Categories

Resources