Closed ghost closed 2 years ago
What exactly are you asking for?
I have updated the post to more detailed.
Drag images can be created today via the IDragSourceHelper
interface. Similarly, drop text can also be created today using the DROPDESCRIPTION
structure and clipboard format, as demonstrated here. Use of either requires a custom IDataObject
implementation because of limitations in the standard Windows Forms one; the latter link provides an example. It would be quite nice if this functionality could be rolled into Windows Forms core.
Note that the drag source supplies the image, but the drop destination supplies the text and icon. You cannot provide label text from a drag source.
Drag images can be created today via the
IDragSourceHelper
interface. Similarly, drop text can also be created today using theDROPDESCRIPTION
structure and clipboard format, as demonstrated here. Use of either requires a customIDataObject
implementation because of limitations in the standard Windows Forms one; the latter link provides an example. It would be quite nice if this functionality could be rolled into Windows Forms core.Note that the drag source supplies the image, but the drop destination supplies the text and icon. You cannot provide label text from a drag source.
I can see this API from microsoft website.
IDragSourceHelper2::SetFlags with flag DSH_ALLOWDROPDESCRIPTIONTEXT
https://docs.microsoft.com/en-us/windows/win32/api/shobjidl/nf-shobjidl-idragsourcehelper2-setflags
It will display the drag image and text at the same time.
Would you like to do a formal API proposal so we can take it to the next level? If you have a POC - it would greatly aid in discussions.
@wjk Can you help me to fill the formal API proposal? My English is not very good. Thank you very much.
Good idea.
New school style drag and drop.
Yes, that's a perfect effect.
In this way, more data and hints can be displayed to users.
@roland5572 - you have really good ideas.
Thank you. I also have some ideas about WPF, if you are interested, you can check it out.
https://github.com/dotnet/wpf/issues/5565 https://github.com/dotnet/wpf/issues/5566
I will check those out.
For this issue, has any progress been made on a proposal?
Okay then if nobody minds, I will take a closer look. I need to learn quite a bit more about drag and drop before I would be comfortable suggesting anything but I think with a little focus it is doable. Drag image and text.
👍
Alpha blended drag image.
Drag image with drop description proof of concept.
https://user-images.githubusercontent.com/5017479/140713761-1b35f272-4818-4fcd-9b20-494691d2307d.mp4
This is awesome stuff! Have you thought about whether we should support for dragging something with a drag source outside of the application? Like picking up a file from Windows to copy into your app.
Thanks, its been really fun. I think adding support for drag images and drop descriptions for drag sources outside of the application would be really helpful. It would allow the application to display more details to the user regarding the drag-and-drop operation.
Drag images and drop descriptions from Explorer.
https://user-images.githubusercontent.com/5017479/141087491-b7d0002f-4362-472f-b919-811fea963dbd.mp4
Awesome! Standing by for your API proposal. Feel free to open a draft PR to accompany it as well.
This will be a stretch for me but I'll start putting it together. I believe there are some other subtler features I haven't looked at yet such as the mouse cursor offset in relation to the drag image and how that allows for some cool things like insertion points with previews.
Note that the outer edges of the drag image are blended out if the image width or height exceeds 300 pixels.
I've hit a little bit of a snag. Drag images don't seem to work well with the RichTextBox and I need some time to figure out why.
Just an update that I'm still researching this issue. Just received 4 books (all released in the 90's) I'm looking through now trying to learn everything I can about drag and drop.
I hope everyone can understand for me there is a big difference between getting some sample code working good enough for a demo versus having a complete understanding of the feature in order to confidently propose a change and see it through. This one could take me a little while to get there.
No worries at all. According to the animations you've made a terrific progress. Feel free to open a draft PR with a sample in our test harness project WinformsControlsTest, it could help in understanding the problem area better and promote discussions.
Will do. I'll start putting together a sample in the test harness.
So far the demos that I've shown come from sample code contained in Adam Root's series on shell style drag and drop. I didn't have to integrate the sample code into Winforms to make the demos work, which was nice since it didn't require me to know how everything works but I could still observe the drag image and drop description behavior and use cases.
Now that I've had some time to study, I'm ready to dive back in. I've started implementing the proof of concept and will open a draft PR when I finish or if I get stuck.
This is out of scope for this issue but I'm noting it here for future reference: Asynchronous drag and drop.
Test harness, using the IDropTargetHelper
interface to display the drag image from Explorer.
https://user-images.githubusercontent.com/5017479/144701231-942d3b5c-9232-4ae0-bc77-e606511d3e39.mp4
It seems a little more within reach.
Test harness, using the IDragSourceHelper2
interface to initialize the drag image and the IDropTargetHelper
interface to display the drag image. When the drag-and-drop helpers are used, they call IDataObject::SetData
and IDataObject::GetData
to load and retrieve private data formats for cross-process support. To facilitate this process, I use the default IDataObject
implementation provided by SHCreateDataObject
which has support for arbitrary data formats.
The new data object is intended to be used in operations such as drag-and-drop, in which the data is stored in the clipboard with a given format.
https://user-images.githubusercontent.com/5017479/144987285-b21186df-35ac-49c0-b86c-415875280461.mp4
I've observed the following data formats used by the drag-and-drop helpers:
Shell IDList Array DragImageBits DragContext DragSourceHelperFlags UsingDefaultDragImage DisableDragText DropDescription DragWindow IsComputingImage IsShowingLayered IsShowingText UntrustedDragDrop
This is really cool!
It's getting better. I discovered how to respond to data requests from Windows Explorer.
Dragging from Explorer to the application, and back. Somebody pinch me.
https://user-images.githubusercontent.com/5017479/145157013-6eb7a0b3-fdc5-45b3-bcbd-08a6eab03720.mp4
So far I've observed the following data formats used by Explorer:
Preferred DropEffect FileDrop UniformResourceLocator FileGroupDescriptorW TargetCLSIDfRelease TargetCLSID AsyncFlag Logical Performed DropEffect Performed DropEffect Shell IDList Array FileNameMapW FileOpFlags DropEffectFolderList
Setting UsingDefaultDragImage to true causes the drag-image manager to display the image like it would when dragged from Explorer, with a layered image background (DD_IMAGEBG) and size of 96 x 96.
UsingDefaultDragImage (true):
UsingDefaultDragImage (false):
Setting UsingDefaultDragImage to true makes the drag image look very good in my opinion. It also seems to be poorly documented territory.
As noted in DROPDESCRIPTION, some UI coloring is applied to the text in Insert if used by specifying %1 in Message.
Without UI coloring.
e.Message = "Copy cat from Explorer";
e.Insert = string.Empty;
With UI coloring.
e.Message = "Copy cat from %1";
e.Insert = "Explorer";
A double percent character %% format marker can be used to output a single percent sign when applying coloring to a drop description message.
e.Message = "Copy cat from %1 100%%";
e.Insert = "Explorer";
We probably want to consider colors of the drag text when the user is using High Contrast. But this is super exciting to see your progress @willibrandon!! I'm very excited.
Thanks @merriemcgaw that is super motivating to hear that. It has been a true test in patience and understanding.
I've just recently got the drag images and drop descriptions working with the RichTextBox.
https://user-images.githubusercontent.com/5017479/146505508-4d4b47bf-6d9c-4ce6-8a2f-6f1ba2eb2363.mp4
Dragging multiple files from Explorer causes the drag-image manager to display a multi-file layered image DD_IMAGEBG with the number of files displayed in the middle DD_TEXTBG.
We probably want to consider colors of the drag text when the user is using High Contrast.
Drag text without UI coloring in the Aquatic high contrast theme.
e.Message = "Copy cat from Explorer";
e.Insert = string.Empty;
Drag text with UI coloring in high contrast. The word "Explorer" has coloring applied.
e.Message = "Copy cat from %1 100%%";
e.Insert = "Explorer";
Here's an example of the drag image in high contrast when UsingDefaultDragImage is set to false, which removes the DD_IMAGEBG and seems to also remove the image alpha-blending.
Multi-file drag from Explorer in high contrast when UsingDefaultDragImage is set to true.
Multi-file drag from Explorer in high contrast when UsingDefaultDragImage is set to false.
@merriemcgaw - This is a good example of why this could take me a while. High contrast themes wasn't something I was aware of.
I'm taking a look at the ToolStripItem next as it has its own DropTarget/DropSource implementation. Please bear with me.
Also I'm starting to think about what automated unit and integration tests could and should look like. Drag-and-drop doesn't seem to be a well tested area at the moment. I only see 2 Control tests and 5 ToolStripItem tests but they are skipped right now due to https://github.com/dotnet/winforms/issues/3336 .
Have a look at the UIIntegration tests, those use InputSimulator to control the mouse and the keyboard.
Have a look at the UIIntegration tests, those use InputSimulator to control the mouse and the keyboard.
@RussKie - Amazing! The mouse drag approach combined with calling DoDragDrop from MouseDown definitely alleviates the issue described in https://github.com/dotnet/winforms/issues/3336 and allows the system to carry on and call IDropTarget::DragEnter when the cursor passes over a drop area. Time to write some tests.
Thank you very much. I could have spent a lot of time looking for that. This should allow us to test every nook and cranny.
As noted in DROPDESCRIPTION and DROPIMAGETYPE, a drop image type can be specified which allows for new and improved drop icons to be used.
DROPIMAGE_INVALID
No drop image preference; use the default image.
e.Effect = DragDropEffects.None;
e.DropIcon = DropIconType.Invalid;
DROPIMAGE_NONE (DD_NONE)
A red bisected circle such as that found on a "no smoking" sign.
e.Effect = DragDropEffects.None;
e.DropIcon = DropIconType.None;
DROPIMAGE_COPY (DD_COPY)
A plus sign (+) that indicates a copy operation.
e.Effect = DragDropEffects.Copy;
e.DropIcon = DropIconType.Copy;
DROPIMAGE_MOVE (DD_MOVE)
An arrow that indicates a move operation.
e.Effect = DragDropEffects.Move;
e.DropIcon = DropIconType.Move;
DROPIMAGE_LINK (DD_CREATELINK)
An arrow that indicates a link.
e.Effect = DragDropEffects.Link;
e.DropIcon = DropIconType.Link;
DROPIMAGE_LABEL (DD_UPDATEMETADATA)
A tag icon that indicates that the metadata will be changed.
e.Effect = DragDropEffects.Move;
e.DropIcon = DropIconType.Label;
DROPIMAGE_WARNING (DD_WARNING)
A yellow exclamation mark that indicates that a problem has been encountered in the operation.
e.Effect = DragDropEffects.Move;
e.DropIcon = DropIconType.Warning;
DROPIMAGE_NOIMAGE
Windows 7 and later. Use no drop image.
e.Effect = DragDropEffects.Move;
e.DropIcon = DropIconType.NoImage;
This is starting to look really good and the drag images and drop descriptions result in a very nice drag-and-drop experience. It makes drag-and-drop more discoverable and easier to use.
I can't help but wonder why it doesn't already exist in Winforms?
I can imagine drag images and drop descriptions being implemented in a few different ways and before I go too far in a certain direction, I suggest we start by first adding support for DropTargets to display the drag image (if one is available) and to specify a drop description. Its a little easier to achieve compared to adding support for DropSources, or more specifically, adding support to specify the drag image.
This is open to change but I'll start the API proposal by exposing the behavior through some additional DragEventArgs, allowing the application to specify a drop description during DragEnter by setting the DropIcon, Message, and Insert arguments. This seems like the least invasive approach and a good place to start.
I'll work on the proposal now and should have a draft ready to go soon, which should help promote the discussion. We can decide which direction to go from there.
👍
I had been wondering if it was possible to extract the drag image itself from the global memory object "DragImageBits" format while in flight so that it could then be passed on to the application to do something cool with it, but I hadn't seen that mentioned in the documentation.
https://user-images.githubusercontent.com/5017479/148196220-b35c265c-2ca3-4f85-9acd-b908c96951a3.mp4
I thought initially I could just extract the drag image bitmap handle from the data object and voila, I have a bitmap. But I kept receiving generic GDI+ errors every time I tried to use the bitmap handle, presumably because it was in use. Fortunately the drag image RGBQUAD array is stored right after the drag image structure in global memory and can be extracted with some knowledge about bottom-up device-independent bitmaps. A good description and diagram illustrating bottom-up DIBs can be found in Top-Down vs. Botton-Up DIBs.
This opens up the possibility to not only specify the drag image, but retrieve it as well.
💥 💥 ⬇️⬇️ Scroll to the API proposal ⬇️⬇️💥 💥
About Winform drag and drop: https://docs.microsoft.com/en-us/dotnet/desktop/winforms/input-mouse/drag-and-drop
Winforms supports drag and drop, but it displays the Windows 2000/XP old school style.
Unlike win10, win10 can provide richer display effects. If you drag and drop a file on Win10, Win10 will display an icon and a text label. Then you can know your specific operation through the text label.
Picture 1: Drag a file:
Picture 2: When you hold down the Control or Alt key, the icon and text will also be changed.
Picture 3: Drag a file to application shortcut, it will display:
So if the drag and drop can provide an Icon and Text properties, the application can display a more detailed operating instruction to users, and the application will be more modern.