I have a GridView that has a column with RepositoryItemCheckEdit as ColumnEdit. I want to disable this control for just one row. How can I do this? Any suggestions?
I have found a solution to the problem.
gridView1.CustomRowCellEditForEditing += OnCustomRowCellEditForEditing;
private void OnCustomRowCellEditForEditing(object sender, CustomRowCellEditEventArgs e)
{
if (e.Column.FieldName != "MyFieldName") return;
*code here*
e.RepositoryItem.ReadOnly = true;
}
you can make the editor read only by handling CustomRowCellEdit:
private void gridView1_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
if(code goes here)
e.RepositoryItem.ReadOnly = true;
}
you can also prevent the editor from being show by handling ShowingEditor:
private void gridView1_ShowingEditor(object sender, CancelEventArgs e)
{
if (code goes here)
e.Cancel = true;
}
in the class that inherits DataGridViewColum override method InitializeEditingControl
it has parameter rowIndex the write something like this
this.DataGridView.EditingControl.Enbale = rowIndex != 3; // or the number you need
Related
I have a DataGridView with cells containing strings. If a cell content is changed, I want to change the background of this cell. What event is the best for doing this?
I first tried the CellValueChanged event, but this is even called by clicking this cell without editing the content.
Here is my function code:
private void GVCrs_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
this.GVCrs.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = Color.Orange;
}
Regards
R4z0R
You can try CellBeginEdit and CellEndEdit events,
string beforeValue = "";
private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
beforeValue = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() != beforeValue)
{
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = Color.Red;
beforeValue = "";
}
}
Result;
Hope helps,
I have tried to code a button such that it is disabled upon form loading however enabled once a textbox has had text entered. My code is below, which is probably familiar:
Public Form()
{
InitializeComponent();
this.button1.enabled = false;
}
private void textbox_TextChanged (object sender, EventArgs e)
{
button1.Enabled = !string.IsNullOrWhiteSpace(textbox.Text);
}
The button indeed loads up disabled, the enabling function doesn't work upon text input and I'm not sure what the issue could be. It is a modal form is that matters. I was wondering if maybe I needed an event listener (although I'm not certain how exactly they work).
Check your Designer.cs file and make sure you have event handler registration there. Something like this:
this.textBox.TextChanged += new System.EventHandler(this.textBox_TextChanged);
Will this work? I can't really see a problem with your code though...
button1.Enabled = textbox.Text != "";
I hope this helps.
May not be the solution to your problem, but this would be the fastest check for one's computer to perform (at least if you let the JIT compiler optimize your code):
button1.Enabled = textbox.Text.Length > 0;
try this
private void Form1_Load(object sender, EventArgs e)
{
button1.Enabled = false;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text))
{
button1.Enabled = true;
}
}
You could try either of the following on the TextChanged property of the TextBox :
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textbox.Text.Length > 0)
{
button1.Enabled = true;
}
else
button1.Enabled = false;
}
or, using the string.IsNullOrEmpty method:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(textbox.Text))
{
button1.Enabled = true;
}
else
button1.Enabled = false;
}
The the below line:
button1.Enabled = !string.IsNullOrWhiteSpace(textbox.Text);
If it didn't work for you or if you are getting an error, then probably because the IsNullOrWhiteSpace method was introduced in .NET 4
In my form application, there is a (buttonNEW) that selects NewIndexRow of DataGridView and I want to change index of datagridview with this button.
private void buttonNew_Click(object sender, EventArgs e)
{
if (dataGridView.CurrentRow.Index!=dataGridView.NewRowIndex)
{
dataGridView.ClearSelection();
dataGridView.Rows[dataGridView.NewRowIndex].Selected = true;
label1.Text = dataGridView.CurrentRow.Index.ToString();
}
}
But after clicking the button the index of DataGridView does not change.
What is the problem?
This should work :-
int numofRows = dataGridView.rows.count;
dataGridView.CurrentCell = dataGridView.Rows[numofRows - 1].Cells[0];
Or I think you could also do this :-
dataGridView.CurrentCell = dataGridView.Rows[dataGridView.NewRowIndex].Cells[0];
Try with Linc:
private void buttonNew_Click(object sender, EventArgs e)
{
dataGridView.Rows.OfType<DataGridViewRow>().Last().Selected = true;
}
I have a winforms app and want to trigger some code when a checkbox embedded in a DataGridView control is checked / unchecked. Every event I have tried either
Triggers as soon as the CheckBox is clicked but before its checked state changes, or
Triggers only once the CheckBox looses its focus
I can't seem to find event that triggers immediately after the checked state changes.
Edit:
What I am trying to achieve is that when the checked state of a CheckBox in one DataGridView changes, the data in two other DataGridViews changes. Yet all the events I have used, the data in the other grids only changes after the CheckBox in the first DataGridView looses focus.
To handle the DatGridViews CheckedChanged event you must first get the CellContentClick to fire (which does not have the CheckBoxes current state!) then call CommitEdit. This will in turn fire the CellValueChanged event which you can use to do your work. This is an oversight by Microsoft. Do some thing like the following...
private void dataGridViewSites_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
dataGridViewSites.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
/// <summary>
/// Works with the above.
/// </summary>
private void dataGridViewSites_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
UpdateDataGridViewSite();
}
P.S. Check this article https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged(v=vs.110).aspx
I found #Killercam's solution to work but was a bit dodgy if the user double clicked too fast. Not sure if other's found that the case either. I found a another solution here.
It uses the datagrid's CellValueChanged and CellMouseUp. Changhong explains that
"The reason for that is OnCellvalueChanged event won’t fire until the DataGridView thinks you have completed editing. This makes senses for a TextBox Column, as OnCellvalueChanged wouldn’t [bother] to fire for each key strike, but it doesn’t [make sense] for a CheckBox."
Here it is in action from his example:
private void myDataGrid_OnCellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
{
// Handle checkbox state change here
}
}
And the code to tell the checkbox it is done editing when it is clicked, instead of waiting till the user leaves the field:
private void myDataGrid_OnCellMouseUp(object sender,DataGridViewCellMouseEventArgs e)
{
// End of edition on each click on column of checkbox
if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
{
myDataGrid.EndEdit();
}
}
Edit: A DoubleClick event is treated separate from a MouseUp event. If a DoubleClick event is detected, the application will ignore the first MouseUp event entirely. This logic needs to be added to the CellDoubleClick event in addition to the MouseUp event:
private void myDataGrid_OnCellDoubleClick(object sender,DataGridViewCellEventArgs e)
{
// End of edition on each click on column of checkbox
if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
{
myDataGrid.EndEdit();
}
}
jsturtevants's solution worked great. However, I opted to do the processing in the EndEdit event. I prefer this approach (in my application) because, unlike the CellValueChanged event, the EndEdit event does not fire while you are populating the grid.
Here is my code (part of which is stolen from jsturtevant:
private void gridCategories_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == gridCategories.Columns["AddCategory"].Index)
{
//do some stuff
}
}
private void gridCategories_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex == gridCategories.Columns["AddCategory"].Index)
{
gridCategories.EndEdit();
}
}
Here is some code:
private void dgvStandingOrder_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dgvStandingOrder.Columns[e.ColumnIndex].Name == "IsSelected" && dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
{
bool isChecked = (bool)dgvStandingOrder[e.ColumnIndex, e.RowIndex].EditedFormattedValue;
if (isChecked == false)
{
dgvStandingOrder.Rows[e.RowIndex].Cells["Status"].Value = "";
}
dgvStandingOrder.EndEdit();
}
}
private void dgvStandingOrder_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgvStandingOrder_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
{
dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
following Killercam'answer, My code
private void dgvProducts_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
dgvProducts.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
and :
private void dgvProducts_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (dgvProducts.DataSource != null)
{
if (dgvProducts.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "True")
{
//do something
}
else
{
//do something
}
}
}
This also handles the keyboard activation.
private void dgvApps_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if(dgvApps.CurrentCell.GetType() == typeof(DataGridViewCheckBoxCell))
{
if (dgvApps.CurrentCell.IsInEditMode)
{
if (dgvApps.IsCurrentCellDirty)
{
dgvApps.EndEdit();
}
}
}
}
private void dgvApps_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// handle value changed.....
}
Ben Voigt found the best solution in a comment-reply above:
private void dgvStandingOrder_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
Seriously, that's ALL you need.
What worked for me was CurrentCellDirtyStateChanged in combination with datagridView1.EndEdit()
private void dataGridView1_CurrentCellDirtyStateChanged( object sender, EventArgs e ) {
if ( dataGridView1.CurrentCell is DataGridViewCheckBoxCell ) {
DataGridViewCheckBoxCell cb = (DataGridViewCheckBoxCell)dataGridView1.CurrentCell;
if ( (byte)cb.Value == 1 ) {
dataGridView1.CurrentRow.Cells["time_loadedCol"].Value = DateTime.Now.ToString();
}
}
dataGridView1.EndEdit();
}
It's all about editing the cell, the problem that is the cell didn't edited actually, so you need to save The changes of the cell or the row to get the event when you click the check box so you can use this function:
datagridview.CommitEdit(DataGridViewDataErrorContexts.CurrentCellChange)
with this you can use it even with a different event.
I have found a simpler answer to this problem. I simply use reverse logic. The code is in VB but it is not much different than C#.
Private Sub DataGridView1_CellContentClick(sender As Object, e As
DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim _ColumnIndex As Integer = e.ColumnIndex
Dim _RowIndex As Integer = e.RowIndex
'Uses reverse logic for current cell because checkbox checked occures
'after click
'If you know current state is False then logic dictates that a click
'event will set it true
'With these 2 check boxes only one can be true while both can be off
If DataGridView1.Rows(_RowIndex).Cells("Column2").Value = False And
DataGridView1.Rows(_RowIndex).Cells("Column3").Value = True Then
DataGridView1.Rows(_RowIndex).Cells("Column3").Value = False
End If
If DataGridView1.Rows(_RowIndex).Cells("Column3").Value = False And
DataGridView1.Rows(_RowIndex).Cells("Column2").Value = True Then
DataGridView1.Rows(_RowIndex).Cells("Column2").Value = False
End If
End Sub
One of the best things about this is no need for multiple events.
I've tried some answers from here, but I've always had some kind of problem (like double clicking or using the keyboard). So, I combined some of them and got a consistent behavior (it's not perfect, but works properly).
void gridView_CellContentClick(object sender, DataGridViewCellEventArgs e) {
if(gridView.CurrentCell.GetType() != typeof(DataGridViewCheckBoxCell))
return;
if(!gridView.CurrentCell.IsInEditMode)
return;
if(!gridView.IsCurrentCellDirty)
return;
gridView.EndEdit();
}
void gridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e) {
if(e.ColumnIndex == gridView.Columns["cFlag"].Index && e.RowIndex >= 0)
gridView.EndEdit();
}
void gridView_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if(e.ColumnIndex != gridView.Columns["cFlag"].Index || e.RowIndex < 0)
return;
// Do your stuff here.
}
The Code will loop in DataGridView and Will check if CheckBox Column is Checked
private void dgv1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex == 0 && e.RowIndex > -1)
{
dgv1.CommitEdit(DataGridViewDataErrorContexts.Commit);
var i = 0;
foreach (DataGridViewRow row in dgv1.Rows)
{
if (Convert.ToBoolean(row.Cells[0].Value))
{
i++;
}
}
//Enable Button1 if Checkbox is Checked
if (i > 0)
{
Button1.Enabled = true;
}
else
{
Button1.Enabled = false;
}
}
}
In the event CellContentClick you can use this strategy:
private void myDataGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 2)//set your checkbox column index instead of 2
{ //When you check
if (Convert.ToBoolean(myDataGrid.Rows[e.RowIndex].Cells[2].EditedFormattedValue) == true)
{
//EXAMPLE OF OTHER CODE
myDataGrid.Rows[e.RowIndex].Cells[5].Value = DateTime.Now.ToShortDateString();
//SET BY CODE THE CHECK BOX
myDataGrid.Rows[e.RowIndex].Cells[2].Value = 1;
}
else //When you decheck
{
myDataGrid.Rows[e.RowIndex].Cells[5].Value = String.Empty;
//SET BY CODE THE CHECK BOX
myDataGrid.Rows[e.RowIndex].Cells[2].Value = 0;
}
}
}
The best way that I found (which also doesn't use multiple events) is by handling the CurrentCellDirtyStateChanged event.
private void dataGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridMatten.CurrentCell.OwningColumn == dataGridMatten.Columns["checkBoxColumn"] && dataGridMatten.IsCurrentCellDirty)
{
dataGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
//your code goes here
}
}
To do this when using the devexpress xtragrid, it is necessary to handle the EditValueChanged event of a corresponding repository item as described here. It is also important to call the gridView1.PostEditor() method to ensure the changed value has been posted. Here is an implementation:
private void RepositoryItemCheckEdit1_EditValueChanged(object sender, System.EventArgs e)
{
gridView3.PostEditor();
var isNoneOfTheAboveChecked = false;
for (int i = 0; i < gridView3.DataRowCount; i++)
{
if ((bool) (gridView3.GetRowCellValue(i, "NoneOfTheAbove")) && (bool) (gridView3.GetRowCellValue(i, "Answer")))
{
isNoneOfTheAboveChecked = true;
break;
}
}
if (isNoneOfTheAboveChecked)
{
for (int i = 0; i < gridView3.DataRowCount; i++)
{
if (!((bool)(gridView3.GetRowCellValue(i, "NoneOfTheAbove"))))
{
gridView3.SetRowCellValue(i, "Answer", false);
}
}
}
}
Note that because the xtragrid doesnt provide an enumerator it is necessary to use a for loop to iterate over rows.
Removing the focus after the cell value changes allow the values to update in the DataGridView. Remove the focus by setting the CurrentCell to null.
private void DataGridView1OnCellValueChanged(object sender, DataGridViewCellEventArgs dataGridViewCellEventArgs)
{
// Remove focus
dataGridView1.CurrentCell = null;
// Put in updates
Update();
}
private void DataGridView1OnCurrentCellDirtyStateChanged(object sender, EventArgs eventArgs)
{
if (dataGridView1.IsCurrentCellDirty)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
You can force the cell to commit the value as soon as you click the checkbox and then catch the CellValueChanged event. The CurrentCellDirtyStateChanged fires as soon as you click the checkbox.
The following code works for me:
private void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
SendKeys.Send("{tab}");
}
You can then insert your code in the CellValueChanged event.
I use DataGridView with VirtualMode=true and only this option worked for me
(when both the mouse and the space bar are working, including repeated space clicks):
private void doublesGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
var data_grid = (DataGridView)sender;
if (data_grid.CurrentCell.IsInEditMode && data_grid.IsCurrentCellDirty) {
data_grid.EndEdit();
}
}
private void doublesGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == CHECKED_COLUMN_NUM && e.RowIndex >= 0 && e.RowIndex < view_objects.Count) { // view_objects - pseudocode
view_objects[e.RowIndex].marked = !view_objects[e.RowIndex].marked; // Invert the state of the displayed object
}
}
this worked for me
private void employeeDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == employeeDataGridView.Columns["employeeStatusColumn"].Index)
{
bool isChecked = (bool)employeeDataGridView.CurrentCell.Value;
if (isChecked)
{
MessageBox.Show("Checked " + isChecked); //out true;
}
else
{
MessageBox.Show("unChecked " + isChecked);
}
}
}
private void employeeDataGridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (employeeDataGridView.DataSource != null)
{
if (e.ColumnIndex == employeeDataGridView.Columns["employeeStatusColumn"].Index && e.RowIndex != -1)
{
employeeDataGridView.EndEdit();
}
}
}
private void dataGridViewPendingBill_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
bool isChecked = (bool) dataGridViewPendingBill[e.ColumnIndex, e.RowIndex].EditedFormattedValue;
if (isChecked)
{
totalAmount += int.Parse(dataGridViewPendingBill.Rows[e.RowIndex].Cells["Amount"].Value.ToString());
textBoxAmount.Text = totalAmount.ToString();
}
else
{
totalAmount -= int.Parse(dataGridViewPendingBill.Rows[e.RowIndex].Cells["Amount"].Value.ToString());
textBoxAmount.Text = totalAmount.ToString();
}
dataGridViewPendingBill.EndEdit();
}
I have few columns in my DataGridView, and there is data in my rows. I saw few solutions in here, but I can not combine them!
Simply a way to right-click on a row, it will select the whole row and show a menu with an option to delete the row and when the option selected it will delete the row.
I made few attempts but none is working and it looks messy. What should I do?
I finally solved it:
In Visual Studio, create a ContextMenuStrip with an item called "DeleteRow"
Then at the DataGridView link the ContextMenuStrip
Using the code below helped me getting it work.
this.MyDataGridView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);
this.DeleteRow.Click += new System.EventHandler(this.DeleteRow_Click);
Here is the cool part
private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
var hti = MyDataGridView.HitTest(e.X, e.Y);
MyDataGridView.ClearSelection();
MyDataGridView.Rows[hti.RowIndex].Selected = true;
}
}
private void DeleteRow_Click(object sender, EventArgs e)
{
Int32 rowToDelete = MyDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
MyDataGridView.Rows.RemoveAt(rowToDelete);
MyDataGridView.ClearSelection();
}
For completness of this question, better to use a Grid event rather than mouse.
First Set your datagrid properties:
SelectionMode to FullRowSelect
and
RowTemplate / ContextMenuStrip to a context menu.
Create the CellMouseDown event:-
private void myDatagridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
int rowSelected = e.RowIndex;
if (e.RowIndex != -1)
{
this.myDatagridView.ClearSelection();
this.myDatagridView.Rows[rowSelected].Selected = true;
}
// you now have the selected row with the context menu showing for the user to delete etc.
}
}
private void dgvOferty_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
{
dgvOferty.ClearSelection();
int rowSelected = e.RowIndex;
if (e.RowIndex != -1)
{
this.dgvOferty.Rows[rowSelected].Selected = true;
}
e.ContextMenuStrip = cmstrip;
}
TADA :D. The easiest way period. For custom cells just modify a little.
It's much more easier to add only the event for mousedown:
private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var hti = MyDataGridView.HitTest(e.X, e.Y);
MyDataGridView.Rows[hti.RowIndex].Selected = true;
MyDataGridView.Rows.RemoveAt(rowToDelete);
MyDataGridView.ClearSelection();
}
}
This is easier. Of cource you have to init your mousedown-event as already mentioned with:
this.MyDataGridView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);
in your constructor.
All the answers posed in to this question are based on a mouse click event. You can also assign a ContenxtMenuStrip to your DataGridview and check if there is a row selected when the user RightMouseButtons on the DataGridView and decide whether you want to view the ContenxtMenuStrip or not. You can do so by setting the CancelEventArgs.Cancel value in the the Opening event of the ContextMenuStrip
private void MyContextMenuStrip_Opening(object sender, CancelEventArgs e)
{
//Only show ContextMenuStrip when there is 1 row selected.
if (MyDataGridView.SelectedRows.Count != 1) e.Cancel = true;
}
But if you have several context menu strips, with each containing different options, depending on the selection, I would go for a mouse-click-approach myself as well.
base on #Data-Base answer it will not work until make selection mode FullRow
MyDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
but if you need to make it work in CellSelect Mode
MyDataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect;
// for cell selection
private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
var hit = MyDataGridView.HitTest(e.X, e.Y);
MyDataGridView.ClearSelection();
// cell selection
MyDataGridView[hit.ColumnIndex,hit.RowIndex].Selected = true;
}
}
private void DeleteRow_Click(object sender, EventArgs e)
{
int rowToDelete = MyDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
MyDataGridView.Rows.RemoveAt(rowToDelete);
MyDataGridView.ClearSelection();
}
private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
MyDataGridView.ClearSelection();
MyDataGridView.Rows[e.RowIndex].Selected = true;
}
}
private void DeleteRow_Click(object sender, EventArgs e)
{
Int32 rowToDelete = MyrDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
MyDataGridView.Rows.RemoveAt(rowToDelete);
MyDataGridView.ClearSelection();
}
private void dataGridView1_CellContextMenuStripNeeded(object sender,
DataGridViewCellContextMenuStripNeededEventArgs e)
{
if (e.RowIndex != -1)
{
dataGridView1.ClearSelection();
this.dataGridView1.Rows[e.RowIndex].Selected = true;
e.ContextMenuStrip = contextMenuStrip1;
}
}
It is work for me without any errors:
this.dataGridView2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);
this.dataGridView2.Click += new System.EventHandler(this.DeleteRow_Click);
And this
private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var hti = dataGridView2.HitTest(e.X, e.Y);
dataGridView2.ClearSelection();
dataGridView2.Rows[hti.RowIndex].Selected = true;
}
}
private void DeleteRow_Click(object sender, EventArgs e)
{
Int32 rowToDelete = dataGridView2.Rows.GetFirstRow(DataGridViewElementStates.Selected);
if (rowToDelete == -1) { }
else
{
dataGridView2.Rows.RemoveAt(rowToDelete);
dataGridView2.ClearSelection();
}
}
You can also make this a little simpler by using the following inside the event code:
private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
rowToDelete = e.RowIndex;
MyDataGridView.Rows.RemoveAt(rowToDelete);
MyDataGridView.ClearSelection();
}
}
See here it can be done using the DataGridView RowTemplate property.
Note: This code isn't tested but I've used this method before.
// Create DataGridView
DataGridView gridView = new DataGridView();
gridView.AutoGenerateColumns = false;
gridView.Columns.Add("Col", "Col");
// Create ContextMenu and set event
ContextMenuStrip cMenu = new ContextMenuStrip();
ToolStripItem mItem = cMenu.Items.Add("Delete");
mItem.Click += (o, e) => { /* Do Something */ };
// This makes all rows added to the datagridview use the same context menu
DataGridViewRow defaultRow = new DataGridViewRow();
defaultRow.ContextMenuStrip = cMenu;
And there you go, as easy as that!
I have a new workaround to come in same result, but, with less code.
for Winforms... That's example is in portuguese
Follow up step by step
Create a contextMenuStrip in your form and create one item
Sign one event click (OnCancelarItem_Click) for this contextMenuStrip
Create a event 'UserDeletingRow' on gridview
and now... you've simulating on key press del from user
you don't forget to enable delete on the gridview, right?!
and finally...