How to drag information from a datagridview Control

Source: Internet
Author: User

Introduction

While doing some recent home-work, I needed to figure out how to implement drag-and-drop fromDatagridviewControl. I had two main controls on the form:ListBoxThat contained a list of categories, andDatagridview
Control that contained a list of products associated with that
Category. To keep things simple, I wanted to be able to drag a product
From the grid toListBoxTo change a product's category.

Starting the drag-and-drop

the first thing I did was to attach an event handler to the datagridview 's mousedown event. because the datagridview
monopolizes the left mouse button, and it is very efficient at
Ming updates, inserts, and deletes, I decided to use the right
mouse button for drag-and-dropping. I didn't need context menus.
(otherwise, I wocould have considering RMB + alt/shift/CTRL clicking ).

  void  grdcampaigns_mousedown ( Object  sender, mouseeventargs E) 
{< br> If (E. button = mousebuttons. right)
{< br> datagridview. hittestinfo info = grdcampaigns. hittest (E. x, E. y);
If (info. rowindex & gt; = 0 )
{< br> datarowview = (datarowview)
grdcampaigns. rows [info. rowindex]. databounditem;
If (view! = null )
grdcampaigns. dodragdrop (view, dragdropeffects. copy);
}< BR >}

The Code tests for the right mouse button. If the RMB was pressed, I have med a hittest using the X and Y components ofMouseeventargs. Because the RMB does not natively interact withDatagridview,
Clicking the RMB will not select a row. If the user clicks the fourth
Row, and the first row was selected (from before), they will
Unwittingly drag the first row, rather than the fourth row. It was not
Intuitive at all.

So I used the information returned by hittest to ensure I was
Working with the row and the column under the mouse pointer, rather
Than the previusly selected row, which made the program much more
Intuitive.

After checking to make sure the data was valid, I passedDatarowviewIntoDodragdropEvent, which started the drag-and-drop operation.

Preparing for the drop

All the above preparation is useless without having a target to drop
The information in. To that end, you need to prepare a drop target. If
You are working with standard data types, this may not be necessary.
Some support may be there already. This is especially true of strings.
For more complex data types, however, such asDatarowview(With which I was working), you will need to provide the plumbing yourself.

This is actually rather easy. First, you need to tell the target it
Is available for drag-and-drop operations. This is done by settingAllowdropProperty of most controlsTrue. Secondly, you need to add code toDragenterEvent of the control.

<SPAN class = "CS-keyword"> void </span> lstcategories_dragenter (<SPAN class = "CS-keyword"> Object </span> sender, drageventargs E) <br >{< br> E. effect = dragdropeffects. copy; <br>}

You can use whatever effect you want, But it shoshould match the effect you used inDodragdropMethod called earlier, when starting the drag. When I tried drag-and-drop without this line of code, it did not work.

Implementing the drop

The last step is to implementDragdropEvent of the target control, and manipulate the data.

<SPAN class = "CS-keyword"> void </span> lstcategories_dragdrop (<SPAN class = "CS-keyword"> Object </span> sender, drageventargs E) <br >{< br> <SPAN class = "CS-keyword"> If </span> (E. data. getdatapresent (<SPAN class = "CS-keyword"> typeof </span> (datarowview ))) <br >{< br> <SPAN class = "CS-comment"> // determine which category the item was draged to </span> <br> point P = lstcategories. pointtoclient (<SPAN class = "CS-Keyword "> New </span> point (e. x, E. y); <br> <SPAN class = "CS-keyword"> int </span> Index = lstcategories. indexfrompoint (p); <br> <SPAN class = "CS-keyword"> If </span> (index & gt; = <SPAN class = "CS-literal"> 0 </span>) <br >{< br> <SPAN class = "CS-comment"> // get references to the category and campaign </span> <br> datarowview Category = (datarowview) lstcategories. items [Index]; <br> datarowview campaign = (datarowview) <br> E. d ATA. getdata (<SPAN class = "CS-keyword"> typeof </span> (datarowview )); <br> <SPAN class = "CS-comment"> // get the old and new category IDs </span> <br> <SPAN class = "CS-keyword"> int </span> newid = (<SPAN class = "CS-keyword"> int </span>) category [<SPAN class = "CS-literal"> 0 </span>]; <br> <SPAN class = "CS-keyword"> int </span> oldid = (<SPAN class = "CS-keyword"> int </span>) campaign [<SPAN class = "CS-literal"> 1 </span>]; <br> <s Pan class = "CS-comment"> // make sure the two do not match </span> <br> <SPAN class = "CS-keyword"> If </span> (oldid! = Newid) <br >{< br> campaign. beginedit (); <br> campaign [<SPAN class = "CS-literal"> 1 </span>] = newid; <br> campaign. endedit (); <br >}< BR>}

The first step I got Med in the drag-drop was to ensure the type
Of data being dropped was the type I expected to receive. This can be
Done throughGetdatapresentMethod, which accepts as its parameter a data type, and returns true if thatTypeIs present.

Once I was sure I had valid data -- or at least the right data type -- I
Got screen coordinates where the dragdrop operation ended. LikeDatagridview
Control before it, I had no idea where the data was going. The user
Cocould drag the product on any visible category: I had to figure out
Which one.

That was accomplished throughIndexfrompointMethod. However, documentation on this special method isVeryPoor, and Microsoft fails to note that you needClientCoordinates for this to work, notScreenCoordinates. So, before you can callIndexfrompoint, You need to convert coordinates from screen to client coordinates using the appropriately namedPointtoclientMethod.

Once I determined (and verified) the category, I cast references
Data items for both the category and the product (Campaign). To save
Unnecessary processing, I checked to make sure the category was in fact
Different.

I shocould point out at this time that I was working with a stronugly-typed dataset , with two tables: Categories and campaigns. both contained the column categoryid ; categoryid is the primary key of categories, and was used for reference in campaigns. the ListBox used in the examples was bound to the categories table in the dataset. whenever the categories list selection changed, a dataview of child rows was retrieved from the dataset , and bound to the datagridview control.

The significance of this point is that when I editCategoryidOf the campaignDatarowviewIn the example above, the associated product listing is removed from the grid, becauseCategoryid
No longer qualifies the product to be in the grid (it is no longer
Child of the current category). When the user clicks on the category
Which the product was moved, however, the product will appear in that
Listing, instead.

All in all, the code was med exactly what I wanted: it was simple,
It worked, and it was intuitive for the user. I doubt I cocould have
Duplicated the results with less code or time any other way.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.