DataGridView navigating to next row - c#

I have a C# winforms application and I am trying to get a button working that will select the next row in a datagridview after the one curently selected.
The code I have so far is:
private void button4_Click(object sender, EventArgs e)
{
try
{
Int32 selectedRowCount = dataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected);
// index out of range on this line
dataGridView1.Rows[dataGridView1.SelectedRows[selectedRowCount].Index].Selected = true;
dataGridView1.FirstDisplayedScrollingRowIndex = selectedRowCount + 1;
}
catch (Exception ex)
{
return;
}
But on running this it throws an exception. Could anyone point out where I may be going wrong. The thrown error is: Index is out of range

try this:
int nRow;
private void Form1_Load(object sender, EventArgs e)
{
nRow = dataGridView1.CurrentCell.RowIndex;
}
private void button1_Click(object sender, EventArgs e)
{
if (nRow < dataGridView1.RowCount )
{
dataGridView1.Rows[nRow].Selected = false;
dataGridView1.Rows[++nRow].Selected = true;
}
}

First, set "Multiselect" property of datagridview to false.
int currentRow = dataGridView1.SelectedRows[0].Index;
if (currentRow < dataGridView1.RowCount)
{
dataGridView1.Rows[++currentRow].Selected = true;
}
It will select the next row in the datagridview.

Select Row and Cell for better solution.
This solution move row indicator on DataGridView.
private void _GotoNext(object sender, EventArgs e)
{
int currentRow = DataGridView1.SelectedRows[0].Index;
if (currentRow < DataGridView1.RowCount - 1)
{
DataGridView1.Rows[++currentRow].Cells[0].Selected = true;
}
}
private void _GotoPrev(object sender, EventArgs e)
{
int currentRow = DataGridView1.SelectedRows[0].Index;
if (currentRow > 0)
{
DataGridView1.Rows[--currentRow].Cells[0].Selected = true;
}
}

It's here:
dataGridView1.SelectedRows[selectedRowCount]
If you have 3 selected rows then selectedRowCount = 3 and there are three rows with indexes: 0, 1, 2.
You are trying to access #3 which doesn't exist.

this example to read value cell or column is number 4 of datagridview
int courow = dataGridView1.RowCount-1;
for (int i=0; i < courow; i++)
{
MessageBox.Show(dataGridView1.Rows[i].Cells[4].Value.ToString());
}

I prefer this row selection :
First check if no multiselect : number_of_data
Then get the select cell (or row) : row_index
private void next_click(object sender, EventArgs e)
{
int number_of_data = dataGridView.SelectedRows.Count;
if (number_of_data > 1) return;
int row_index = dataGridView.SelectedCells[0].RowIndex;
if (row_index < dataGridView.RowCount-1)
{
dataGridView.Rows[row_index++].Selected = false;
dataGridView.Rows[row_index].Selected = true;
}
// Do something
}

enter code here private void Form1_Load(object sender, EventArgs e)
{
X = dataGridView1.CurrentCell.RowIndex;//int x;
}
enter code here private void button2_Click(object sender, EventArgs e)
{
if (dataGridView1.Rows.Count > 0)
{
this.dataGridView1.ClearSelection();
dataGridView1.Rows[0].Selected = true;
}
}
enter code here private void button3_Click(object sender, EventArgs e)
{
if (X < dataGridView1.RowCount)
{
if (X != dataGridView1.RowCount - 1)
{
dataGridView1.ClearSelection();
dataGridView1.Rows[++X].Selected = true;
}
else
{
button2_Click(sender, e);//this else with make it loop
X = 0;
}
}
}

dgv_PhotoList.Rows[dgv_PhotoList.CurrentRow.Index+1].Selected = true;

Related

Previous button not working for DataGridView C#

How can I fix the previous button to move backward in dataGridView row?
The next button is working.
It does nothing.
I don't know how to fix that. Any ideas? I would appreciate it.
Here is my code:
int nRow;
private void Form1_Load
{
nRow = DataGridView2.CurrentCell.RowIndex;
}
private void PreviousData_Click
{
if (row>=0)
{
if (row!=0)
{
DataGridView2.Rows[row].Selected = false;
DataGridView2.Rows[--row].Selected = true;
}
else
{
MessageBox.Show("Need More Data!");
}
}
}
int row;
private void DataGridView2_CellClick
{
if (DataGridView2.SelectedRows.Count != -1)
{
row = DataGridView2.CurrentRow.Index;
}
}
Bind the following two events to your previous and next buttons, respectively and it will do the job.
private void PreviousData_Click(object sender, EventArgs e)
{
var currentRow = DataGridView2.CurrentCell.RowIndex;
if (currentRow == 0)
return;
else
currentRow--;
DataGridView2.ClearSelection();
DataGridView2.CurrentCell = DataGridView2.Rows[currentRow].Cells[0];
DataGridView2.Rows[currentRow].Selected = true;
}
private void NextData_Click(object sender, EventArgs e)
{
var currentRow = DataGridView2.CurrentCell.RowIndex;
if (currentRow == DataGridView2.RowCount - 1)
return;
else
currentRow++;
DataGridView2.ClearSelection();
DataGridView2.CurrentCell = DataGridView2.Rows[currentRow].Cells[0];
DataGridView2.Rows[currentRow].Selected = true;
}

C# - ListView : How to handle the mouse click event on a listViewItem?

Let's say I have a ListView on a form and it is populated with records.
How can I do this : when I click (single click) on a row , something has to happen - for example MessageBox.Show("row selected");
How to make this happen? Do I need a mouse click event ? And how can I do this?
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var selectedItemText = (listBox1.SelectedItem ?? "(none)").ToString();
MessageBox.Show("Selected: " + selectedItemText);
}
private void listBox1_MouseClick(object sender, MouseEventArgs e)
{
for (int i = 0; i < listBox1.Items.Count; i++)
{
var rectangle = listBox1.GetItemRectangle(i);
if (rectangle.Contains(e.Location))
{
MessageBox.Show("Item " + i);
return;
}
}
MessageBox.Show("None");
}
#Tommy answer is for ListBox, this one is for ListView :
private void listView1_MouseClick(object sender, MouseEventArgs e)
{
for (int i = 0; i < listView1.Items.Count; i++)
{
var rectangle = listView1.GetItemRect(i);
if (rectangle.Contains(e.Location))
{
//Write your code here
return;
}
}
}
To prevent unwished behavior on ListView with checkboxes my solution is:
private void lvMembers_MouseClick(object sender, MouseEventArgs e)
{
for (int itemIndex = 0; itemIndex < lvMembers.Items.Count; itemIndex++)
{
ListViewItem item = lvMembers.Items[itemIndex];
Rectangle itemRect = item.GetBounds(ItemBoundsPortion.Label);
if (itemRect.Contains(e.Location))
{
item.Checked = !item.Checked;
break;
}
}
}
If you want to select listview item on mouse click over it try this.
private void timeTable_listView_MouseUp(object sender, MouseEventArgs e)
{
Point mousePos = timeTable_listView.PointToClient(Control.MousePosition);
ListViewHitTestInfo hitTest = timeTable_listView.HitTest(mousePos);
try
{
int columnIndex = hitTest.Item.SubItems.IndexOf(hitTest.SubItem);
edit_textBox.Text = timeTable_listView.SelectedItems[0].SubItems[columnIndex].Text;
}
catch(Exception)
{
}
}

Condensing lots of Button Click Events

I have 40 buttons that all do something slightly different when clicked, I would like to condense this down if I can. I also want to say, if one of the buttons is clicked, create a timestamp which can be accessed by the class.
Here is the code for 2 out of 40 of the buttons:
private void Btn1_Click(object sender, RoutedEventArgs e)
{
for (int i = 1; i < 5; i++)
{
CheckBox CheckBox = (this.FindName(string.Format("Check{0}", i)) as CheckBox);
if (CheckBox != null)
{
CheckBox.IsChecked = true;
}
}
}
private void BtnDisable1_Click(object sender, RoutedEventArgs e)
{
for (int i = 1; i < 5; i++)
{
CheckBox CheckBox1 = (this.FindName(string.Format("Check_D{0}", i)) as CheckBox);
if (CheckBox1 != null)
{
CheckBox1.IsChecked = false;
}
}
}
I think one way of doing it is putting it in an array and whenever one of the 40 buttons are clicked it looks in the array on what to do next? I'm not really sure, thank you!
You can make this simple using one method.
Answer is updated based on this discussion
private void DoWork(int checkboxGroup, bool enable)
{
int start = checkboxGroup * 4;
for (int i = start; i < start + 4; i++)
{
CheckBox CheckBox = this.FindName("CheckBox" + i) as CheckBox;
if (CheckBox != null)
{
CheckBox.IsChecked = enable;
}
}
}
private void Btn1_Click(object sender, RoutedEventArgs e)
{
DoWork(1 , true);
}
private void BtnDisable1_Click(object sender, RoutedEventArgs e)
{
DoWork(1 , false);
}
Because there are 40 methods like this you can use Expression bodied methods. You must have C#6 to use this feature.
private void Btn1_Click(object sender, RoutedEventArgs e) => DoWork(1 , true);
private void BtnDisable1_Click(object sender, RoutedEventArgs e) => DoWork(1 , false);
private void Btn2_Click(object sender, RoutedEventArgs e) => DoWork(2, true);
private void BtnDisable2_Click(object sender, RoutedEventArgs e) => DoWork(2, false);
// and so on

How to count checked checkboxes in DataGridView when Checkbox value is changed in c#?

I was unable to count checked checkboxes in DataGridView. I want to count the checked checkboxes during the checkbox is checked and store the number of checked items in a label. I tried the following code but does not give the correct count:
int num = 0;
private void dgvLoadData_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
bool isChecked = Convert.ToBoolean(dgvLoadData.Rows[dgvLoadData.CurrentCell.RowIndex].Cells[0].Value.ToString());
if (isChecked)
{
num+=1;
}
else
{
num-=1;
}
labelSelectedSum.Text = "Selected Items: " + num;
}
Apply CurrentCellDirtyStateChanged event on the table. Call gridview.CommitEdit to update value of the checkbox column. Do the following:
private void dgvLoadData_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvLoadData.IsCurrentCellDirty)
{
dgvLoadData.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
That will call _CellValueChanged event. No changes will be done on the codes inside CellValueChanged event:
int num = 0;
private void dgvLoadData_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
return;
bool isChecked = (bool)dgvItemsToShip.Rows[e.RowIndex].Cells[0].Value;
if (isChecked)
{
num+=1;
}
else
{
num-=1;
}
labelSelectedSum.Text = "Selected Items: " + num;
}
You can use the event: CellContentClick and CellContentDoubleClick:
Good Luck!
int num = 0;
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
bool isChecked = (bool)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue;
CheckCount(isChecked);
}
private void dataGridView1_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
bool isChecked = (bool)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue;
CheckCount(isChecked);
}
private void CheckCount(bool isChecked)
{
if (isChecked)
{
num++;
}
else
{
num--;
}
labelSelectedSum.Text = "Selected Items: " + num;
}
I have a DataTable bound to my DataGridView and I check if the first column has any checkbox checked
Here is my example :
private void dataGridViewMain_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0)
{
int numberOfRow = dataTableCsvFile.AsEnumerable().Count(r => r[0].ToString() == true.ToString());
buttonDataGridviewVerify.Enabled = numberOfRow > 0;
}
}

Programmatically added DataGridViewRow gets lost

As described in the topic, I'm trying to add a new Row to my Datagridview.
In the Constructor of the form I'm setting AllowUserToAddRows to false.
I'm still able to add the row programmatically but it doesn't seem to get saved in my Settings File.
Here's the code of my form - I left some (hopefully not essential) parts out:
P.S.: pay attention to my comment at the end of my btnAddEntry_Click()-Method
public DataSettings()
{
InitializeComponent();
//Import rows that are saved int settings
for (int i = 0; i < Properties.Settings.Default.colNames.Count; i++)
{
dgv.Rows.Add(new DataGridViewRow());
dgv.Rows[i].Cells[0].Value = Properties.Settings.Default.colNames[i];
dgv.Rows[i].Cells[1].Value = Properties.Settings.Default.colStarts[i];
dgv.Rows[i].Cells[2].Value = Properties.Settings.Default.colWidths[i];
}
//Hide "new row"-row
dgv.AllowUserToAddRows = false;
}
private void cancel_Click(object sender, EventArgs e)
{
this.Dispose();
}
private void save_Click(object sender, EventArgs e)
{
Properties.Settings.Default.colNames = new System.Collections.Specialized.StringCollection();
Properties.Settings.Default.colStarts = new System.Collections.Specialized.StringCollection();
Properties.Settings.Default.colWidths = new System.Collections.Specialized.StringCollection();
foreach (DataGridViewRow row in dgv.Rows)
{
if (row.Index < dgv.Rows.Count - 1)
{
Properties.Settings.Default.colNames.Add((String)row.Cells[0].Value);
Properties.Settings.Default.colStarts.Add((String)row.Cells[1].Value);
Properties.Settings.Default.colWidths.Add((String)row.Cells[2].Value);
}
}
Properties.Settings.Default.Save();
this.DialogResult = DialogResult.OK;
}
private void btnAddEntry_Click(object sender, EventArgs e)
{
dgv.AllowUserToAddRows = true;
Dialogs.Data_AddRow newRow = new Dialogs.Data_AddRow();
newRow.ShowDialog();
dgv.Rows.Add(new string[] { newRow.parmName, newRow.parmStart, newRow.parmWidth });
newRow.Dispose();
dgv.AllowUserToAddRows = false; //If I comment out this line - It works fine.
//but then the "newrow"-row is visible
}
private void btnDeleteEntry_Click(object sender, EventArgs e)
{
dgv.Rows.Remove(dgv.SelectedRows[0]);
}
private void btnDeleteAll_Click(object sender, EventArgs e)
{
dgv.Rows.Clear();
}
You are losing info of last row because of this line: (row.Index < dgv.Rows.Count - 1) should be (row.Index < dgv.Rows.Count) or just get rid of it.
If you want to check if the last row is not NewRow when saving do this:
foreach (DataGridViewRow row in dgv.Rows)
{
if (!row.IsNewRow)
{
Properties.Settings.Default.colNames.Add((String)row.Cells[0].Value);
Properties.Settings.Default.colStarts.Add((String)row.Cells[1].Value);
Properties.Settings.Default.colWidths.Add((String)row.Cells[2].Value);
}
}

Categories

Resources