1
votes

I have a C# WinForms application with a GridView on a Form wich shows records from the database containing blobs (files PDF/JPG/etc.) stored in a database.

I can doubleclick on a row in the grid, to write the blob to disk and open the file. I can single-click on rows to select one or more rows (using ctrl+shift) I can drag files onto the grid to add the files as rows to the grid (and database)

Now I want the user to be able to drag one or more rows from the grid to, for instance, the desktop or a mailclient but cannot figure out in what event to start the 'drag' operation.

When a user selects one or more file he/she does that using the left-mousebutton, dragging uses the same left-mousebutton, both events trigger the mouse-down event. How does one determine what the user is about to do?

I have tried starting the drag operation in the mouse-down event, but that doesn't work if I want to select multiple rows, every time I click on a row a drag operation starts...

how is that handled in the windows explorer for instance? How does one detect what the user is trying to do?

3
In MouseDown you should make a note of the location, and then while you get MouseMove without a MouseUp, you can calculate the distance moved. If the mouse moves more than a certain distance (say 12 pixels in either X or Y) then start a drag.Matthew Watson
Matthew is right, but use SystemInformation.DragSize Property (msdn.microsoft.com/en-us/library/…) instead of 12 pixelsViacheslav Ivanov

3 Answers

8
votes

I have got it working now. However I did not use a timer as suggested.

In Mouse-Down I set a flag and store X,Y point, then in mouse-up I reset the flag and in Mouse-move I calculate movement based on stored X,Y poiny, when movement is more that 10pixels in X or Y direction I start drag-operation.

Here's the code.

'

    private bool DraggingFromGrid = false;
    private System.Drawing.Point DraggingStartPoint = new System.Drawing.Point(  );

    void GridControlBrowser_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            DraggingFromGrid = true;
            DraggingStartPoint = new System.Drawing.Point(e.X, e.Y);
        }
    }

    void GridControlBrowser_MouseUp(object sender, MouseEventArgs e)
    {
        if (DraggingFromGrid)
        {
            DraggingFromGrid = false;
        }
    }

    void GridControlBrowser_MouseMove(object sender, MouseEventArgs e)
    {
        if (DraggingFromGrid)
        {
            if (System.Math.Abs(e.X - DraggingStartPoint.X) > 10 ||
                System.Math.Abs(e.Y - DraggingStartPoint.Y) > 10)
            {
                StartDragging();
            }
        }
    }

    private void StartDragging()
    {
        DraggingFromGrid = false;

        // create files
        var _criteria = this.GetSelectionFromGrid();
        var _files = new List<string>();

        ... retrieve filenames and store in _files List ...

        var _data = new DataObject(DataFormats.FileDrop, _files.ToArray());

        DoDragDrop(_data, DragDropEffects.Copy);
    }

'

1
votes

I had a similar issue in that adding dragging to a form was interfering with existing double click functionality. I found a very simple solution:

void GridControlBrowser_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
    if (e.Clicks != 2)
    {
        StartDragging();
    }
}

This cancels dragging if there is a double click so that double clicking continues to work.

0
votes

there is more then one way to do that. I strongly suggest you try some of them until you decide what's best for you. for example, you can use the mouse_down event to start the drag and drop by using a timer. if the user is clicking the mouse more then 0.5 seconds, u start the drag. the mouse_up event kill the drag/dropping. another way is making the drag and drop only with some key pressed while clicking the mouse.