implementing dragdrop whilst allowing click

D

David J Rose

I am having trouble allowing a user to drag an item, whilst also allowing
them to click the item. I am using mousedown, mousemove and mouseup. It
works if I click the button carefully, but if there is any mouse movement,
then it is interpreted as a drag, and the click does not work. What I want
is a way to only do the drag if the mouse movement is above a threshold. Is
this possible?

Here is the basic code:

private void ItemToolStripButton_MouseDown(object sender, MouseEventArgs e)
{
ToolStripButton btn = ((ToolStripButton)sender);
if (e.Button == MouseButtons.Right)
{
//show contextmenu
}
else
{
bMouseDown = true;
}
}

private void ItemToolStripButton_MouseMove(object sender, MouseEventArgs e)
{
if ((bMouseDown) && (e.Button == MouseButtons.Left))
{
ToolStripButton btn = ((ToolStripButton)sender);
btn.DoDragDrop(btn.Tag, DragDropEffects.Copy);
}
}
}

private void ItemToolStripButton_MouseUp(object sender, MouseEventArgs e)
{
ToolStripButton btn = ((ToolStripButton)sender);
if (e.Button != MouseButtons.Right)
{
//perform the onclick code here
bMouseDown = false;
}

Much Thanks
 
A

Alan Pretre

David J Rose said:
I am having trouble allowing a user to drag an item, whilst also allowing
them to click the item. I am using mousedown, mousemove and mouseup. It
works if I click the button carefully, but if there is any mouse movement,
then it is interpreted as a drag, and the click does not work. What I want
is a way to only do the drag if the mouse movement is above a threshold. Is
this possible?

There's a whole bunch of events, such as

DragDrop
DragEnter
DragLeave
DragOver
ItemDrag

that you need to set up. In addition, there is a property called AllowDrop
that needs to be turned on. Using these things the system will initiate and
do the drag and drop operation for you.

-- Alan
 
D

David J Rose

I believe that all the events mentioned are for accepting a dragged item. I
am talking about starting the drag-drop operation using the DoDragDrop
method.

Any more ideas?
 
A

Alan Pretre

David J Rose said:
I believe that all the events mentioned are for accepting a dragged item. I
am talking about starting the drag-drop operation using the DoDragDrop
method.

Sorry, I guess I should have asked you where you are dragging from. If you
are dragging from a listview or a treeview, you do the DoDragDrop() call in
the ItemDrag event, not MouseDown.

-- Alan
 
J

John B

David said:
I am having trouble allowing a user to drag an item, whilst also allowing
them to click the item. I am using mousedown, mousemove and mouseup. It
works if I click the button carefully, but if there is any mouse movement,
then it is interpreted as a drag, and the click does not work. What I want
is a way to only do the drag if the mouse movement is above a threshold. Is
this possible?

Its sort of kludgy but you could define your threshhold (say 200ms) and
start a timer in the mousedown event which when fired would do the
dragdrop only if the mouse is still down.

Havent tried though, I have had the same sort of problem with other tree
views, spec. infragistics activetree in vb6.

JB
 
G

Guest

I'm facing the same problem as David is. I have a series of radio buttons
that look like regular buttons. Originally they were just designed to select
a different option. But now I want to add Drag & Drop capability so that
their order can be changed.

My first thought was to immediately back out of the MouseDown event (which
initiates Drag & Drop) if the radioButton wasn't already checked. That works
okay but isn't exactly the effect I'd ideally like.

So I'd love to get more feedback on here if the timer suggestion is the
preferred approach to resolve this issue ... or are there other approaches?
 
G

Guest

I want to follow up with what John B wrote (and thank him!) for quickly
finding me a solution to this problem.

First, I googled for: c# timer mousedown
and found this article:
http://www.informit.com/articles/article.asp?p=101720&seqNum=21&rl=1

I quickly grasped the leapfrogging the author was suggesting, along with
stopping the timer if the mouse button is released quickly enough. Here's
the code I wrote for my application, which are a series of Question buttons.
Hopefully this code can help others too:


// Initiate a dedicated timer. If the user holds down the mouse long
enough then we'll assume he wants to drag & drop.
private void QuestionButton_MouseDown(object sender, MouseEventArgs e)
{
ClickedQuestionButton = sender; // Store a reference to this
button because 'QuestionButtonTimer_Tick' can't access it otherwise
questionButtonTimer.Enabled = true;
}

// ... Otherwise if he lets go quickly then we'll assume he just wants
to click the question button instead.
private void QuestionButton_MouseUp(object sender, MouseEventArgs e)
{
questionButtonTimer.Enabled = false;
ClickedQuestionButton = null; // Just cleaning up
}

// Initiates drag & drop visual effects
private void QuestionButtonTimer_Tick(object sender, EventArgs e)
{
questionButtonTimer.Enabled = false;

QuestionButton qBut = ClickedQuestionButton as QuestionButton;
ClickedQuestionButton = null; // Just cleaning up
qBut.DoDragDrop(qBut, DragDropEffects.All);
}


In my case, it's imperative to know which QuestionButton (of several) is
being dragged, so that's why I created a module-level private variable to
temporarily store it. I don't think it's necessary to set this variable to
null but I thought it was cleaner this way.

For now I'm going to take John B's advice and use 200ms as the delay time.
I suppose that it might be prudent to allow this value to be shortened or
lengthened depending on a user's preference.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top