Drag and Drop one control to another control in winform - c#

am doing something very very simple.
I have a listbox whose events are set like this :
public Form1()
{
InitializeComponent();
this.listBox1.AllowDrop = true;
this.listBox1.DragEnter += new DragEventHandler(listBox1_DragEnter);
this.listBox1.DragDrop += new DragEventHandler(listBox1_DragDrop);
}
void listBox1_DragDrop(object sender, DragEventArgs e)
{
//code to add labelText to Items of ListBox
}
void listBox1_DragEnter(object sender, DragEventArgs e)
{
//set DragDropEffects;
}
now I have a label, code for which is as follows:
private void label1_MouseDown(object sender, MouseEventArgs e)
{
DoDragDrop((sender as Label).Text, DragDropEffects.Copy);
//this.label1.DoDragDrop((sender as Label).Text, DragDropEffects.Copy);
//used one of them at a time.
}
but nothing happens. listbox DragEnter event never fires up. in fact, drag never happens.
whenever i try to drag label (text), not allowed windows cursor appears, instead of 'DragDropEffects.Copy's cursor
Drag and Drop doesn't take place..
when I modify the listbox (and the associated code) to accept files to be dropped on it from any other window, that works perfectly.
so..am unable to perform drag from a control kept on the form to another control kept on the same form.
am I missing something? am running windows XP.
I went through this and through this
please help...

Your code does work actually.
You just have to set the right drag effects in your event handlers.
void listBox1_DragDrop(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
void listBox1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}

Check if ListBox.AllowDrop is set to TRUE or not

The following is an example of what you need, with all the code (adding it here for whoever finds this post).
#region Initial Values
//Constructor:
public Form1() {
InitializeComponent();
}
private void Form1_Load( object sender, EventArgs e ) {
InitialValues();
}
private void InitialValues() {
PrepareDragAndDrop();
}
#endregion Initial Values
#region Drag & Drop
private void PrepareDragAndDrop() {
//For the object that receives the other dragged element:
TheSamplListBox.AllowDrop = true;
TheSamplListBox.DragEnter += TheSamplListBox_DragEnter;
TheSamplListBox.DragLeave += TheSamplListBox_DragLeave;
TheSamplListBox.DragDrop += TheSamplListBox_DragDrop;
//For the object that will be dragged:
TheSampleLabel.MouseDown += ( sender, args ) => DoDragDrop( TheSampleLabel.Text, DragDropEffects.Copy );
}
private void TheSamplListBox_DragEnter( object theReceiver, DragEventArgs theEventData ) {
theEventData.Effect = DragDropEffects.Copy;
//Only the code above is strictly for the Drag & Drop. The following is for user feedback:
//You can use [TheSamplListBox] but this approach allows for multiple receivers of the same type:
var theReceiverListBox = (ListBox) theReceiver;
theReceiverListBox.BackColor = Color.LightSteelBlue;
}
private void TheSamplListBox_DragLeave( object theReceiver, EventArgs theEventData ) {
//No code here for the Drag & Drop. The following is for user feedback:
//You can use [TheSamplListBox] but this approach allows for multiple receivers of the same type:
var theReceiverListBox = (ListBox) theReceiver;
theReceiverListBox.BackColor = Color.White;
}
private void TheSamplListBox_DragDrop( object theReceiver, DragEventArgs theEventData ) {
//You can use [TheSamplListBox] but this approach allows for multiple receivers of the same type:
var theReceiverListBox = (ListBox) theReceiver;
//Get the data being dropped. In this case, a string:
var theStringBeingDropped = theEventData.Data.GetData( "System.String" );
//Add the string to the ListBox:
theReceiverListBox.Items.Add( theStringBeingDropped );
//Only the code above is strictly for the Drag & Drop. The following is for user feedback:
theReceiverListBox.BackColor = Color.White;
}
#endregion Drag & Drop
.

Related

How can I make images drag and drop-able to reorder them?

I'm building an application in which I'd like a user to be able to reorder pictures in a form in two columns. I've got a flowLayoutPanel of a set width, and pictures are added via the OpenFileDialog and scaled to half the width (minus an allowance for a scroll bar) of the flow layout panel.
This is where I'm stuck - I've tried adding the images as Labels, Buttons, and now PictureBoxes and I can't work out how to actually move them around. I gave up on labels because CanSelect is false - although I didn't know if that would have made a difference - and I moved on from buttons because I realised picture boxes existed. I'm open to switching out which controls I use but the images will always need to be in two columns.
Here's the code I currently have for the DragEnter and DragDrop events:
private void flowLayoutPanel_6_Cards_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
private void flowLayoutPanel_6_Cards_DragDrop(object sender, DragEventArgs e)
{
MessageBox.Show("dropped");
}
How can I implement this? What controls should I use and what properties should I be looking at to make this possible?
So thanks to #TaW's comment I now know that you have to add a DoDragDrop call to the MouseDown event on whatever you're dragging. My now-working code is below (thanks mostly to this tutorial):
private void flowLayoutPanel_6_Cards_DragDrop(object sender, DragEventArgs e)
{
PictureBox picture = (PictureBox)e.Data.GetData(typeof(PictureBox));
FlowLayoutPanel _source = (FlowLayoutPanel)picture.Parent;
FlowLayoutPanel _destination = (FlowLayoutPanel)sender;
if (_source != _destination)
{
//where did you even get this from?
}
else
{
Point p = _destination.PointToClient(new Point(e.X, e.Y));
var item = _destination.GetChildAtPoint(p);
int index = _destination.Controls.GetChildIndex(item, false);
_destination.Controls.SetChildIndex(picture, index);
_destination.Invalidate();
}
}
private void flowLayoutPanel_6_Cards_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
void p_MouseDown(object sender, MouseEventArgs e)
{
PictureBox p = (PictureBox)sender;
p.DoDragDrop(p, DragDropEffects.All);
}

Drag drop between two forms with two datagridviews c#

I have recently finished my drag drop event between two datagridviews on my main form, and it works well. Now, however, I have decided to make a change that requires datagridview2 to be on another form (form2). Can anyone tell me how to drag drop between two datagridviews, while on separate forms?
Below is my existing code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));
dataGridView1.Rows[dataGridView1.HitTest(clientPoint.X, clientPoint.Y).RowIndex].Cells[dataGridView1.HitTest(clientPoint.X, clientPoint.Y).ColumnIndex].Value = (System.String)e.Data.GetData(typeof(System.String));
}
}
private void dataGridView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void dataGridView2_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex > -1 && e.ColumnIndex > -1)
dataGridView2.DoDragDrop(
dataGridView2.Rows[e.RowIndex]
.Cells[e.ColumnIndex]
.Value.ToString(),
DragDropEffects.Copy);
}
I my opinion drag and drop between two different forms work same like on one form. Are you sure that dataGridView1 property AllowDrop is set to True?

Dragging and Dropping in WPF

I've got a TreeView and Canvas in my WPF application. I'm trying to implement functionality whereby users can drag a TreeViewItem and a method should be called when the user drops on the canvas, passing the TreeViewItem header as a parameter to this method.
This is what I've done so far:
private void TreeViewItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.Source.GetType().Name.Equals("TreeViewItem"))
{
TreeViewItem item = (TreeViewItem)e.Source;
if (item != null)
{
DataObject dataObject = new DataObject();
dataObject.SetData(DataFormats.StringFormat, item.Header.ToString());
DragDrop.DoDragDrop(item, dataObject, DragDropEffects.Copy);
}
}
}
When I drag and drop to the canvas nothing happens. I am thus unsure of what I should do next. I feel that it's something really small, but I'm at a loss. How can I call the method and detect that the header has been dropped?
Any ideas?
You need to set AllowDrop to true on your target element and then handle DragOver and Drop events on the target element.
Example:
private void myElement_DragOver(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(typeof(MyDataType)))
{
e.Effects = DragDropEffects.None;
e.Handled = true;
}
}
private void myElement_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(MyDataType)))
{
// do whatever you want do with the dropped element
MyDataType droppedThingie = e.Data.GetData(typeof(MyDataType)) as MyDataType;
}
}

ObjectListView drag and drop to RichTextBox

So I have an objectlistview (actually a treelistview). I want to be able to drag an item from this onto a richtextbox, and have it insert a property of the dragged item (in this case Default_Heirarchy_ID)
The TreeListView's objectmodel is a List<T> of a class called SpecItem.
This is what I have so far:
public frmAutospecEditor(SpecItem siThis_, List<SpecItem> lstStock_)
{
InitializeComponent();
txtFormula.DragEnter += new DragEventHandler(txtFormula_DragEnter);
txtFormula.DragDrop += new DragEventHandler(txtFormula_DragDrop);
...
}
void txtFormula_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void tlvSpecItem_ItemDrag(object sender, ItemDragEventArgs e)
{
int intID = ((SpecItem)tlvSpecItem.GetItem(tlvSpecItem.SelectedIndex).RowObject).Default_Heirarchy_ID ??0;
DoDragDrop(intID, DragDropEffects.Copy);
}
private void txtFormula_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
object objID = e.Data.GetData(typeof(String));
//this is where it goes wrong - no matter what I try to do with this, it
//always returns either null, or the text displayed for that item in the TreeListView,
//NOT the ID as I want it to.
string strID = (string)objID;
txtFormula.Text = strID;
}
Where am I going wrong?
Cheers
The Drag is the control you want to take data from (your OLV).
The Drop is the destination control (your textbox). So:
Set the IsSimpleDragSource property of your OLV to true.
In the textbox set AllowDrop property to true. Then handle the DragEnter event of your textbox and use the DragEventArgs param.
Handle the ModelDropped event:
private void yourOlv_ModelDropped(object sender, ModelDropEventArgs e)
{
// If they didn't drop on anything, then don't do anything
if (e.TargetModel == null) return;
// Use the dropped data:
// ((SpecItem)e.TargetModel)
// foreach (SpecItem si in e.SourceModels) ...
// e.RefreshObjects();
}
Read more: http://objectlistview.sourceforge.net/cs/dragdrop.html#ixzz1lEt7LoGr

AllowDrop property not working for ToolStripItems

I have successfully created DragDrop functionality with user controls. Now I am trying to allow DragDrop functionality on some components such as ToolStripButton.
The base class, ToolStripItem, supports AllowDrop and the DragEnter/DragDrop events...
ToolStripButton hides these properties in the designer, but they are publicly accessable.
Originally I tried doing the following for each ToolStripButton:
button.AllowDrop = true;
button.DragEnter += new DragEventHandler(button_DragEnter);
button.DragDrop += new DragEventHandler(button_DragDrop);
However, the events were not ever firing. These buttons are contained within a MenuStrip, so I changed the MenuStrip.AllowDrop to true. Then I started getting DragEnter and DragDrop events, but the DragDrop event would fail due to a threading/invoke problem when accessing the Tag property of the ToolStripItem.
The ToolStripItems cannot be invoked upon. So I have tried invoking their container, the MenuStrip, with the same function. I am still getting a threading/invoke problem where the thread stops running as soon as I try to access the ToolStripItem.
Here is the code I'm using to retrieve the Tag information after invoke:
void button_DragDrop(object sender, DragEventArgs e)
{
menuStrip.Invoke(new DragEventHandler(MyDragFunction), new object[] { sender, e });
}
void MyDragFunction(object sender, DragEventArgs e)
{
int id = (int)((ToolStripButton)sender).Tag;
// Debugging never reaches this line
int dragId = (int)e.Data.GetData(DataFormatName, false);
MoveItem(id, dragId);
}
Is Drag and Drop to a component like a ToolStripItem simply not possible? Or am I doing something wrong?
Here is the code I got to work for me.
I assign the DragDrop properties in the form constructor since they are hidden in the designer.
foreach (object o in menuStrip.Items)
{
if (o is ToolStripButton)
{
ToolStripItem item = (ToolStripItem)o;
item.AllowDrop = true;
item.DragEnter += new DragEventHandler(item_DragEnter);
item.DragOver += new DragEventHandler(item_DragOver);
item.DragDrop += new DragEventHandler(item_DragDrop);
}
}
private void item_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormatName, false))
{
e.Effect = DragDropEffects.Move;
}
}
private void item_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormatName, false))
{
e.Effect = DragDropEffects.Move;
}
}
private void item_DragDrop(object sender, DragEventArgs e)
{
int id = (int)e.Data.GetData(DataFormatName, false);
int category = Convert.ToInt32((sender as ToolStripButton).Tag);
MyFunction(category, id);
}

Categories