I have got a DataGridView with a MultiSelect=True in C#.
I want to limit the maximum number of simultaneously selected rows to 2, so that user can select only one or two rows at the same time. How can I achive this?
There are no events like BeforeSelectedRowsChanged or ValidatingSelectedRows.
My DataGridView is Readonly also.
** EDIT **
my SelectionMode is FullRowSelect
On the SelectionChanged event you can do this:
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.SelectedCells.Count > 2)
{
dataGridView1.SelectedCells[0].Selected = false;
}
}
This will prevent/undo selecting any more cells after selecting two.
For whole rows:
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 2)
{
dataGridView1.SelectedRows[0].Selected = false;
}
}
This always leave selected 2 last selected rows
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 2)
{
for (int i = 2; i < dataGridView1.SelectedRows.Count; i++)
{
dataGridView1.SelectedRows[i].Selected = false;
}
}
}
You could try overriding SetSelectedRowCore, calling the base with adding your new limitation to the selected condition.
protected virtual void SetSelectedRowCore(int rowIndex,bool selected )
{
base(rowIndex, selected && currentSelection < allowedSelectionCount);
}
SetSelectedRowCore
could you please inform me how to display the row number of data grid view on label or text box to be able to use it in update or delete table.
I tried the following but it display nothing when i click on the data grid view cells
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
DataGridViewRow row = dataGridView1.Rows[rowIndex];
textBox9.Text = dataGridView1.Rows[0].Cells[1].Value.ToString();
}
I use this:
private void tableConteudo_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex != -1)
{
_myObjectVar = (MyObject)table1.Rows[e.RowIndex].DataBoundItem;
}
}
So, instead of using a CellContentClick, you can use CellClick event.
try this,
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
textBox9.Text = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
}
Windows Forms application (c#).
I have two ComboBoxes.
If I select an item in one, I want the text in the other one to be blank.
This is what I have:
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox2.Text = "";
}
private void ComboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox1.Text = "";
}
... but as you can see, when I make a selection in one, the text in both ComboBoxes get cleared.
How to accomplish this?
Thank you.
Try setting the ComboBox.SelectedIndex to -1
A zero-based index of the currently selected item. A value of negative
one (-1) is returned if no item is selected.
or rather based on your specifications try something lie
private bool changed = false;
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (!changed)
{
changed = true;
ComboBox2.Text = "";
changed = false;
}
}
private void ComboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
if (!changed)
{
changed = true;
ComboBox1.Text = "";
changed = false;
}
}
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...
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