Drag'n'drop - GiveFeedback event never called

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I am trying to implement drag and drop in a C# app, but for some reason I
can't get it to call the GiveFeedback event. I have done everything by the
book as far as I can tell, but a breakpoint in the GiveFeedback event is
simply never reached. I know that's not much to go on, but if anyone can
suggest what I might have missed I'd be very grateful.
 
Dave, maybe you can show us some sample code that exemplifies the problem?
e.g. the call(s) to DoDragDrop(), definition of your event handler and how
you're adding the delegate to the event?
 
OK. Here goes. I'll try and keep it brief while hopefully including
everything important. I'm actually using drag and drop to implement a bar
control (as a UserControl) that can be picked up at either end and shortened
or lengthened. Thre is a set of bars, each bar is made up of a row of
buttons, the whole being implemnted as a 2-dim array of Button objects.
Because of the way it works the DragDrop event is not required. There are
also no DragOver or DragQueryContinue events implemented. I want to use
GiveFeedback in order to set a two-headed arrow cursor.
So:
// FormLoad event creates the buttons in ButtonArray:
ButtonArray = new Button[Rows, Columns];
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
ButtonArray[row, col] = new Button();
// Stuff to set up the button, size location etc. Omitted.
ButtonArray[row, col].MouseDown +=
new MouseEventHandler(Button_MouseDown);
ButtonArray[row, col].DragEnter +=
new DragEventHandler(Button_DragEnter);
ButtonArray[row, col].GiveFeedback +=
new GiveFeedbackEventHandler(Button_GiveFeedback);
ButtonArray[row, col].AllowDrop = true;
Controls.Add(ButtonArray[row, col]);
}
}

//Drag and drop starts in the MouseDown event:
private void Button_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Stuff to check the cursor is at the end of a row, etc. Omitted.
DoDragDrop(sender, DragDropEffects.Move);
// DragDrop effect is irrelevant for my purpose, but I have tried
various values.
// I can change which of the standard cursors is displayed, but not
get it to call
// GiveFeedback
}
}

private void Button_DragEnter(object sender, DragEventArgs e)
{
// Check that the cursor is still in the same row
if (GetRow((Button)sender) ==
GetRow((Button)e.Data.GetData(typeof(Button))))
{
// Stuff to work out which direction the cursor is moving and change
the colour
// of the buttons. Omitted.
e.Effect = e.AllowedEffect; // Allows whatever effect I set in
MouseDown
}
else
{
e.Effect = DragDropEffects.None; // Shows a No Entry cursor
}
}

private void Button_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
bool setBreakpointHere = true; // Never reached
}

Hope that helps. Thanks for taking a look.
 
Hi Dave. DoDragDrop() and the GiveFeedback event apply to a particular
control, in unison. If you're calling DoDragDrop() on your Form control, the
GiveFeedback handler needs to be linked to the form (instead or as well).
You're linking the GiveFeedback handler to the each of the buttons. Since
you're not calling DoDragDrop on one of the buttons, it will not have the
opportunity to provide feedback on that drag-drop operation. i.e. since a
button hasn't performed the drag-drop it can't provide feedback.

Alternatively, in your MouseDown handler you could get the button to which
the event applies by casting the sender object to a Button object (e.g.
Button button = sender As Button) and calling DoDragDrop for the button
object (e.g. button.DoDragDrop(this, DragDropEffects.Move) or
button.DoDragDrop(sender, DragDropEffects.Move))

--
http://www.peterRitchie.com/


Dave said:
OK. Here goes. I'll try and keep it brief while hopefully including
everything important. I'm actually using drag and drop to implement a bar
control (as a UserControl) that can be picked up at either end and shortened
or lengthened. Thre is a set of bars, each bar is made up of a row of
buttons, the whole being implemnted as a 2-dim array of Button objects.
Because of the way it works the DragDrop event is not required. There are
also no DragOver or DragQueryContinue events implemented. I want to use
GiveFeedback in order to set a two-headed arrow cursor.
So:
// FormLoad event creates the buttons in ButtonArray:
ButtonArray = new Button[Rows, Columns];
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
ButtonArray[row, col] = new Button();
// Stuff to set up the button, size location etc. Omitted.
ButtonArray[row, col].MouseDown +=
new MouseEventHandler(Button_MouseDown);
ButtonArray[row, col].DragEnter +=
new DragEventHandler(Button_DragEnter);
ButtonArray[row, col].GiveFeedback +=
new GiveFeedbackEventHandler(Button_GiveFeedback);
ButtonArray[row, col].AllowDrop = true;
Controls.Add(ButtonArray[row, col]);
}
}

//Drag and drop starts in the MouseDown event:
private void Button_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Stuff to check the cursor is at the end of a row, etc. Omitted.
DoDragDrop(sender, DragDropEffects.Move);
// DragDrop effect is irrelevant for my purpose, but I have tried
various values.
// I can change which of the standard cursors is displayed, but not
get it to call
// GiveFeedback
}
}

private void Button_DragEnter(object sender, DragEventArgs e)
{
// Check that the cursor is still in the same row
if (GetRow((Button)sender) ==
GetRow((Button)e.Data.GetData(typeof(Button))))
{
// Stuff to work out which direction the cursor is moving and change
the colour
// of the buttons. Omitted.
e.Effect = e.AllowedEffect; // Allows whatever effect I set in
MouseDown
}
else
{
e.Effect = DragDropEffects.None; // Shows a No Entry cursor
}
}

private void Button_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
bool setBreakpointHere = true; // Never reached
}
 
Wow. I never would have figured that out (the way the example in the help is
put together I don't think that point is really illustrated, or maybe I just
missed it.) Big thanks. I'll give it a go.
I can't see any particular reason to do it one way rather than the other
(call and event both in the control or both in the button), can you?
--
Dave


Peter Ritchie said:
Hi Dave. DoDragDrop() and the GiveFeedback event apply to a particular
control, in unison. If you're calling DoDragDrop() on your Form control, the
GiveFeedback handler needs to be linked to the form (instead or as well).
You're linking the GiveFeedback handler to the each of the buttons. Since
you're not calling DoDragDrop on one of the buttons, it will not have the
opportunity to provide feedback on that drag-drop operation. i.e. since a
button hasn't performed the drag-drop it can't provide feedback.

Alternatively, in your MouseDown handler you could get the button to which
the event applies by casting the sender object to a Button object (e.g.
Button button = sender As Button) and calling DoDragDrop for the button
object (e.g. button.DoDragDrop(this, DragDropEffects.Move) or
button.DoDragDrop(sender, DragDropEffects.Move))

--
http://www.peterRitchie.com/


Dave said:
OK. Here goes. I'll try and keep it brief while hopefully including
everything important. I'm actually using drag and drop to implement a bar
control (as a UserControl) that can be picked up at either end and shortened
or lengthened. Thre is a set of bars, each bar is made up of a row of
buttons, the whole being implemnted as a 2-dim array of Button objects.
Because of the way it works the DragDrop event is not required. There are
also no DragOver or DragQueryContinue events implemented. I want to use
GiveFeedback in order to set a two-headed arrow cursor.
So:
// FormLoad event creates the buttons in ButtonArray:
ButtonArray = new Button[Rows, Columns];
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
ButtonArray[row, col] = new Button();
// Stuff to set up the button, size location etc. Omitted.
ButtonArray[row, col].MouseDown +=
new MouseEventHandler(Button_MouseDown);
ButtonArray[row, col].DragEnter +=
new DragEventHandler(Button_DragEnter);
ButtonArray[row, col].GiveFeedback +=
new GiveFeedbackEventHandler(Button_GiveFeedback);
ButtonArray[row, col].AllowDrop = true;
Controls.Add(ButtonArray[row, col]);
}
}

//Drag and drop starts in the MouseDown event:
private void Button_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Stuff to check the cursor is at the end of a row, etc. Omitted.
DoDragDrop(sender, DragDropEffects.Move);
// DragDrop effect is irrelevant for my purpose, but I have tried
various values.
// I can change which of the standard cursors is displayed, but not
get it to call
// GiveFeedback
}
}

private void Button_DragEnter(object sender, DragEventArgs e)
{
// Check that the cursor is still in the same row
if (GetRow((Button)sender) ==
GetRow((Button)e.Data.GetData(typeof(Button))))
{
// Stuff to work out which direction the cursor is moving and change
the colour
// of the buttons. Omitted.
e.Effect = e.AllowedEffect; // Allows whatever effect I set in
MouseDown
}
else
{
e.Effect = DragDropEffects.None; // Shows a No Entry cursor
}
}

private void Button_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
bool setBreakpointHere = true; // Never reached
}
 
Hi Dave. Yes, it's not clear from the documentation; it took me more than
one try...

If I were subclassing a control, I may be inclined to have the control deal
with the drag-drop (in that case you should be dealing with overrides and not
events). Since you're not subclassing Button, I would suggest just letting
the Form-based class deal with the drag-drop. e.g continue with DoDragDrop()
from the Form's Button_MouseDown() but link the GiveFeedback event handler to
your Form class. I'm assuming the parent of the buttons is a Form-based
class...

--
http://www.peterRitchie.com/


Dave said:
Wow. I never would have figured that out (the way the example in the help is
put together I don't think that point is really illustrated, or maybe I just
missed it.) Big thanks. I'll give it a go.
I can't see any particular reason to do it one way rather than the other
(call and event both in the control or both in the button), can you?
--
Dave


Peter Ritchie said:
Hi Dave. DoDragDrop() and the GiveFeedback event apply to a particular
control, in unison. If you're calling DoDragDrop() on your Form control, the
GiveFeedback handler needs to be linked to the form (instead or as well).
You're linking the GiveFeedback handler to the each of the buttons. Since
you're not calling DoDragDrop on one of the buttons, it will not have the
opportunity to provide feedback on that drag-drop operation. i.e. since a
button hasn't performed the drag-drop it can't provide feedback.

Alternatively, in your MouseDown handler you could get the button to which
the event applies by casting the sender object to a Button object (e.g.
Button button = sender As Button) and calling DoDragDrop for the button
object (e.g. button.DoDragDrop(this, DragDropEffects.Move) or
button.DoDragDrop(sender, DragDropEffects.Move))

--
http://www.peterRitchie.com/


Dave said:
OK. Here goes. I'll try and keep it brief while hopefully including
everything important. I'm actually using drag and drop to implement a bar
control (as a UserControl) that can be picked up at either end and shortened
or lengthened. Thre is a set of bars, each bar is made up of a row of
buttons, the whole being implemnted as a 2-dim array of Button objects.
Because of the way it works the DragDrop event is not required. There are
also no DragOver or DragQueryContinue events implemented. I want to use
GiveFeedback in order to set a two-headed arrow cursor.
So:
// FormLoad event creates the buttons in ButtonArray:
ButtonArray = new Button[Rows, Columns];
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
ButtonArray[row, col] = new Button();
// Stuff to set up the button, size location etc. Omitted.
ButtonArray[row, col].MouseDown +=
new MouseEventHandler(Button_MouseDown);
ButtonArray[row, col].DragEnter +=
new DragEventHandler(Button_DragEnter);
ButtonArray[row, col].GiveFeedback +=
new GiveFeedbackEventHandler(Button_GiveFeedback);
ButtonArray[row, col].AllowDrop = true;
Controls.Add(ButtonArray[row, col]);
}
}

//Drag and drop starts in the MouseDown event:
private void Button_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Stuff to check the cursor is at the end of a row, etc. Omitted.
DoDragDrop(sender, DragDropEffects.Move);
// DragDrop effect is irrelevant for my purpose, but I have tried
various values.
// I can change which of the standard cursors is displayed, but not
get it to call
// GiveFeedback
}
}

private void Button_DragEnter(object sender, DragEventArgs e)
{
// Check that the cursor is still in the same row
if (GetRow((Button)sender) ==
GetRow((Button)e.Data.GetData(typeof(Button))))
{
// Stuff to work out which direction the cursor is moving and change
the colour
// of the buttons. Omitted.
e.Effect = e.AllowedEffect; // Allows whatever effect I set in
MouseDown
}
else
{
e.Effect = DragDropEffects.None; // Shows a No Entry cursor
}
}

private void Button_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
bool setBreakpointHere = true; // Never reached
}
 
That's what I've done, and it seeme to work fine. Many thanks
--
Dave


Peter Ritchie said:
Hi Dave. Yes, it's not clear from the documentation; it took me more than
one try...

If I were subclassing a control, I may be inclined to have the control deal
with the drag-drop (in that case you should be dealing with overrides and not
events). Since you're not subclassing Button, I would suggest just letting
the Form-based class deal with the drag-drop. e.g continue with DoDragDrop()
from the Form's Button_MouseDown() but link the GiveFeedback event handler to
your Form class. I'm assuming the parent of the buttons is a Form-based
class...

--
http://www.peterRitchie.com/


Dave said:
Wow. I never would have figured that out (the way the example in the help is
put together I don't think that point is really illustrated, or maybe I just
missed it.) Big thanks. I'll give it a go.
I can't see any particular reason to do it one way rather than the other
(call and event both in the control or both in the button), can you?
--
Dave


Peter Ritchie said:
Hi Dave. DoDragDrop() and the GiveFeedback event apply to a particular
control, in unison. If you're calling DoDragDrop() on your Form control, the
GiveFeedback handler needs to be linked to the form (instead or as well).
You're linking the GiveFeedback handler to the each of the buttons. Since
you're not calling DoDragDrop on one of the buttons, it will not have the
opportunity to provide feedback on that drag-drop operation. i.e. since a
button hasn't performed the drag-drop it can't provide feedback.

Alternatively, in your MouseDown handler you could get the button to which
the event applies by casting the sender object to a Button object (e.g.
Button button = sender As Button) and calling DoDragDrop for the button
object (e.g. button.DoDragDrop(this, DragDropEffects.Move) or
button.DoDragDrop(sender, DragDropEffects.Move))

--
http://www.peterRitchie.com/


:

OK. Here goes. I'll try and keep it brief while hopefully including
everything important. I'm actually using drag and drop to implement a bar
control (as a UserControl) that can be picked up at either end and shortened
or lengthened. Thre is a set of bars, each bar is made up of a row of
buttons, the whole being implemnted as a 2-dim array of Button objects.
Because of the way it works the DragDrop event is not required. There are
also no DragOver or DragQueryContinue events implemented. I want to use
GiveFeedback in order to set a two-headed arrow cursor.
So:
// FormLoad event creates the buttons in ButtonArray:
ButtonArray = new Button[Rows, Columns];
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Columns; col++)
{
ButtonArray[row, col] = new Button();
// Stuff to set up the button, size location etc. Omitted.
ButtonArray[row, col].MouseDown +=
new MouseEventHandler(Button_MouseDown);
ButtonArray[row, col].DragEnter +=
new DragEventHandler(Button_DragEnter);
ButtonArray[row, col].GiveFeedback +=
new GiveFeedbackEventHandler(Button_GiveFeedback);
ButtonArray[row, col].AllowDrop = true;
Controls.Add(ButtonArray[row, col]);
}
}

//Drag and drop starts in the MouseDown event:
private void Button_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Stuff to check the cursor is at the end of a row, etc. Omitted.
DoDragDrop(sender, DragDropEffects.Move);
// DragDrop effect is irrelevant for my purpose, but I have tried
various values.
// I can change which of the standard cursors is displayed, but not
get it to call
// GiveFeedback
}
}

private void Button_DragEnter(object sender, DragEventArgs e)
{
// Check that the cursor is still in the same row
if (GetRow((Button)sender) ==
GetRow((Button)e.Data.GetData(typeof(Button))))
{
// Stuff to work out which direction the cursor is moving and change
the colour
// of the buttons. Omitted.
e.Effect = e.AllowedEffect; // Allows whatever effect I set in
MouseDown
}
else
{
e.Effect = DragDropEffects.None; // Shows a No Entry cursor
}
}

private void Button_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
bool setBreakpointHere = true; // Never reached
}
 

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

Back
Top