Drag&Drop: DataGridView rows "between" TabPage - c#

[Solved] I want to drag some DataGridViewRows from a DataGridView, contained in a TabPage, to another DataGridView also contained in another TabPage. I have set the DataGridView's Event (How could I Drag and Drop DataGridView Rows under each other?), but i don't know how I can "navigate" between TabPages!

Here's a bare bone example how I can drag text from one textbox on a tab to another one on a separate tab:
private void textBox1_MouseDown(object sender, MouseEventArgs e)
{
textBox1.DoDragDrop(textBox1.Text, DragDropEffects.Copy | DragDropEffects.Move);
}
private void tabControl1_DragOver(object sender, DragEventArgs e)
{
Point location = tabControl1.PointToClient(Control.MousePosition);
for (int tab = 0; tab < tabControl1.TabCount; ++tab)
{
if (tabControl1.GetTabRect(tab).Contains(location))
{
tabControl1.SelectedIndex = tab;
break;
}
}
}
private void textBox2_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void textBox2_DragDrop(object sender, DragEventArgs e)
{
textBox2.Text = e.Data.GetData(DataFormats.Text).ToString();
}
NOTE: You must set AllowDrop property to true on the TabControl, and of course on the destination control.
Cheers

I have solved the question by myself (and #mrlucmorin) :
internal void dgv_MouseDown(object sender, MouseEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
List<DataGridViewRow> result = new List<DataGridViewRow>();
foreach(DataGridViewRow row in dgv.SelectedRows)
{
result.Add(row);
}
dgv.DoDragDrop(result, DragDropEffects.Copy | DragDropEffects.Move);
}
private void dgv_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void dgv_DragDrop(object sender, DragEventArgs e)
{
try
{
DataGridView dataGridView1 = (DataGridView)sender;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
rows = (List<DataGridViewRow>)e.Data.GetData(rows.GetType());
//some stuff
}
}

Related

textbox textchange event to click the checkbox in datagridview

I have a textbox and a datagridview with checkbox. The excel import into datagridview. I add the checkbox into datagridview. I want to input the number into textbox and this number will match the column in datagridview.
please help me!
private void TextBox2_TextChanged(object sender, EventArgs e)
{
}
private void TextBox2_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if(e.KeyCode==Keys.Enter)
{
button4.Focus();
Button4_Click(sender,e);
textBox2.Focus();
}
}
private void Button4_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[3].Value.ToString() == textBox2.Text)
{
row.Cells[0].Value = ((CheckBox)dataGridView1.Controls.Find("DataGridViewCheckBoxCell", true)[0]).Checked;
}
}
}
private void Form9_Load(object sender, EventArgs e)
{
TextBox textBox = new TextBox();
textBox.TextChanged += new EventHandler(TextBox2_TextChanged);
}
Set this property when setting up your DataGridView
dataGridView1.Columns[0].ValueType = typeof(CheckState);
And then in your Event Handler set the cell using this
if (row.Cells[3].Value.ToString() == textBox2.Text)
{
row.Cells[0].Value = CheckState.Checked;
}

C # Drag and drop both directions

I want to drag and drop between listbox and more than one textbox in both directions but when I double click an item in listbox it doubles. I don't know fow to change the drag over latency here is my code for the listbox
Mouse Down event
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (listBox1.Items.Count == 0)
return;
int index = listBox1.IndexFromPoint(e.X, e.Y);
string s = listBox1.Items[index].ToString();
DragDropEffects dde1 = DoDragDrop(s, DragDropEffects.All);
if (dde1 == dragdropeffects.all)
{
listbox1.items.removeat(listbox1.indexfrompoint(e.x, e.y));
} ...
Drag and drop event
private void listBox1_DragDrop(object sender, DragEventArgs e)
{
//if (e.Data.GetDataPresent(DataFormats.StringFormat))
//{
// string str = (string)e.Data.GetData(
// DataFormats.StringFormat);
// listBox1.Items.Add(str);
//}
}
Dragover event
private void listBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}

Drog and Drop TableLayoutPanel in a panel?

I'm trying a drag and drop for a tablelayoutpanel in a panel using winforms/c#, the drag of the tablelayout works successfully but the problem is that the tablelayoutpanel droped doesn't appear !!
any solution please ??
private void Registration_Load(object sender, EventArgs e)
{
panel2.AllowDrop = true;
tableLayoutPanel1.AllowDrop = true;
panel2.DragEnter += panel2_DragEnter;
panel2.DragDrop += panel2_DragDrop;
tableLayoutPanel1.MouseDown += tableLayoutPanel1_MouseDown;
}
private void panel2_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void panel2_DragDrop(object sender, DragEventArgs e)
{
((TableLayoutPanel)e.Data.GetData(typeof(TableLayoutPanel))).Parent (Panel)sender;
}
private void tableLayoutPanel1_MouseDown(object sender, MouseEventArgs e)
{
tableLayoutPanel1.DoDragDrop(tableLayoutPanel1, DragDropEffects.Move);
}
The code is inadequate, you'll need to at least set the Location property of the dropped TLP to ensure it is within the panel bounds and/or located at the mouse cursor. And the Z-order matters, setting the Parent property puts it at the bottom so it can easily be overlapped by other controls in the panel, you need BringToFront().
Try this:
private void panel2_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(typeof(TableLayoutPanel))) e.Effect = DragDropEffects.Move;
}
private void panel2_DragDrop(object sender, DragEventArgs e) {
var tlp = (TableLayoutPanel)e.Data.GetData(typeof(TableLayoutPanel));
tlp.Location = panel2.PointToClient(new Point(e.X, e.Y));
tlp.Parent = panel2;
tlp.BringToFront();
}

How can I save definitely the new location of a TableLayoutPanel after a drag and drop in a panel?

I'm trying a drag and drop for a tablelayoutpanel in a panel using winforms/c#, the drag and drop of the tablelayoutpanel works successfully but how can I save the new location of the tablelayoutpanel using a button action ? Any solution please ?
private void Registration_Load(object sender, EventArgs e)
{
panel2.AllowDrop = true;
tableLayoutPanel1.AllowDrop = true;
panel2.DragEnter += panel2_DragEnter;
panel2.DragDrop += panel2_DragDrop;
tableLayoutPanel1.MouseDown += tableLayoutPanel1_MouseDown;
}
private void panel2_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(TableLayoutPanel))) e.Effect = DragDropEffects.Move;
}
private void panel2_DragDrop(object sender, DragEventArgs e)
{
var tlp = (TableLayoutPanel)e.Data.GetData(typeof(TableLayoutPanel));
tlp.Location = panel2.PointToClient(new Point(e.X, e.Y));
tlp.Parent = panel2;
tlp.BringToFront();
}
private void tableLayoutPanel1_MouseDown(object sender, MouseEventArgs e)
{
tableLayoutPanel1.DoDragDrop(tableLayoutPanel1, DragDropEffects.Move);
}
i find a solution to my problem. the idea is to save the location of the items in the database (Location.X a,d Location.Y) then in the load page we fix the location of the dropped item with the location saved in the database.

Right click to select a row in a Datagridview and show a menu to delete it

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...

Categories