Ticket T1062932
Visible to All Users

Drag and drop between two grids easy setup

created 3 years ago (modified 3 years ago)

Hello, I am trying to prepare an easy setup to activate drag and drop between two grids.

Edit: now I discovered that BehaviorManager must be placed onto the grid to make the Drag And Drop Behavior option display in Run Designer window.
How can I use BehaviorManager to set up drag and drop between two grids when each grid is contained in a UserControl (both UC of same type) because there is an additional buttons bar etc?

What I want to achieve in total:
Clipboard-File-6.png

I have been trying to generalize the drag and drop setup from this ticket
https://supportcenter.devexpress.com/ticket/details/e694 into a method which could be put into a Utilities class. Then in my project, I would simply call this method and drag and drop would work between two grids.

Also, DragAndDropCursors class which should be an enum of cursors to be used to set e.Cursor in drag and drop handling doesn't work for me as it is not an enum but in the examples, it is. See this ticket for example: https://supportcenter.devexpress.com/ticket/details/t638165, it uses DragAndDropCursors as if it were an enum.
Clipboard-File-2.png

Could you please help me find out why my code doesn't work and maybe simplify my "utility" method but also keep the option to transform the data between two grids if the data source was not the same? I would like to have "mouse cursor with rectangle sign" cursor for the drag and drop which signifies "moving" But I cannot choose this cursor from the default system Cursors enum/collection as far as I know.

Note: The ticket E694 isn't exactly where I started from with my example code because I started from an early version of the E694 example which was posted in a support ticket which I lost URL to.
In the early version of E694, some drag and drop setup had to be done also in code in addition to the behaviorManager1 present.
In the latest version of the E694 example (https://supportcenter.devexpress.com/ticket/details/e694, there is no additional setup in code of Form1.cs and there are even no events assigned to the behaviors.
I think that everything what was done was to create a behaviorManager and assign two grids to it which seems very clean and easy.

In this latest version of the E694 example, the whole target gridcontrol is glowing in blue when the items are dragged over it. I cannot see anything like that in my example. How is it achieved?
Clipboard-File-4.png

I am adding the code of my attempt in a .zip archive. It is not ideal because I have been struggling with the drag and drop setup for multiple hours today so I am maybe not paying attention to all details.

My final requirement for the utility function to enable drag and drop between two grids would be:

  1. the types of data source can differ, I need to provide a transformation function between type 1 and type 2 and vice versa (but default type 1 = type 2 and no transformation function)
  2. choose cursor

Thank you,

Jiri

Answers approved by DevExpress Support

created 3 years ago (modified 3 years ago)

Hello Jiri,

Thank you for the project.

You are correct, you need to add a Drag-And-Drop Behavior to the BehaviorManager and attach it both of your grids. As mentioned in the move data items section, if both Data Grids/Tree Lists have the same columns and their underlying data sources expose API to add and remove items, no more actions are required. If data structure differs, you need to handle drag events to convert data items. Please note that you need to add the BehaviorManager within the form and initialize it with the form's components, otherwise it will get disposed of and not work due to garbage collection. Then, modify your utility class to receive a BehaviorManager object from the form and use the object to create the behaviors.

When grids are compatible, you do not need to handle their drag-and-drop events. The blue preview area that you mentioned can be modified in the DragOver event using the InserIndicator, InsertIndicatorSize, and InsertIndicatorLocation properties. You can obtain a Cursor object from the standard Cursors class and assign it to the DragOverEventArgs.Cursor property. The DragAndDropCursors are no longer supported by default. For more details regarding this change, see the following ticket: DragAndDropCursors no longer holds built in cursors.

When the Handled property is set to true in the event handler, the default drag-and-drop operation is suppressed. In this case, you need to manually implement the operation. You can use the Data property included in the event's arguments to determine the row handles of data being dragged to the grid. Use this to get the data from the source grid, transform it and add it to the target grid's data source in your DragDrop event handler.

I hope you find this information useful. Should you require further assistance, let me know.

See also:
DevExpress WinForms Cheat Sheet - Drag-and-Drop Within/Between Controls

    Comments (2)

      Thank you,
      I now understand a bit more.

      Regarding the cursor, what is the suggested way to achieve selecting non-system cursors? The thread you posted a link to mentions that the class is now moved to internal API and it is not recommended to use it. What is the public API replacement for selecting a cursor from DragAndDropCursors then?

      Thus, you can get the required cursor using the GetCursor method in the latest version as follows:

      C#
      using DevExpress.Portable.Input; e.Cursor = DragAndDropCursors.GetCursor(DevExpress.Portable.Input.PortableDragDropEffects.Move).ToPlatform();

      However, I would like to note that this class is our inner API that might be changed in the future. Since DragAndDropCursors is an undocumented class, these changes will not be displayed on our Breaking Change list and you may need to update your code when upgrading our components.
      Thus, I do not recommend you use this class in your application.

      I have studied this section of the drag and drop behavior documentation and tried using the BehaviorManager exactly as in the documentation in my application. The result was that drag and drop is initiated but the grids don't accept the dragged data.
      Both grids show this cursor when dragged over with data:
      Clipboard-File-1.png
      I then tried to create a sample project which is only two grids and the BehaviorManager but the result is the same - the "drop blocked" cursor.
      What am I doing wrong?
      Please see the attached video and sample project.

      Christian Santos (DevExpress Support) 3 years ago

        Hi Jiri,

        Thank you for the project and video.

        We have switched to using the standard Cursor object, which is the recommended object to assign to the DragOverEventArgs.Cursor property. You can use a non-system cursor as long as it is a standard Cursor object. See the Cursors In C# article for more details. If you want to use the built-in cursors, then a workaround is to use the ToPlatform extension method as mentioned in this ticket.

        We are going to improve this behavior. In the future, the DragOverEventArgs.Cursor property will not need to be set and the DragOverEventArgs.Action property, like .NET's standard DragDropEffects property, will be able to determine the cursor.

        Regarding the blocked cursor and the grid not accepting dragged data, these are because your grid's data source is unable to initiate the default drag-and-drop operation. I checked your project and noticed that you used a List object as your grid's data source. The List class does not support adding or removing rows with our grid. As such, use a BindingList or BindingSource instead to enable the operation. I recommend that you read the following articles that describe this in greater detail:

        If you wish to modify the default drag-and-drop operation, you need to modify the Cursor by handling the DragOver event. Then, handle the DragDrop event to accept the dragged data and manually add it to your target grid's data source. Please note that you need to set the Handled property to true to if you want to suppress the default drag-and-drop operation. Otherwise, your changes will be overwritten and ignored.

        I hope you find this information useful. Let me know if you have additional questions.

        Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

        Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.