-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to implement drag & drop with CefSharp WinForms #1593
Comments
Try searching We're moving towards using Gitter Chat. Please ask followup questions there. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I'm posting my current workaround for whoever may need similar functionality. This works, as in, we are able to override the CefSharp drag event and do whatever we want, while preventing CEF from loading the dragged content as an HTML file. However, since we are responding to the DragOver event, even if the user cancels the drag (ie. hovers over the browser without releasing the mouse button) the event will fire.
|
@annevu - Can you check this? |
@hgupta9 I went with using the WPF implementation. If I have time after my project, I will explore your workaround and let you know. Thanks for posting it! |
I ended up going with an implementation similar to @hgupta9's, since there isn't an OnDragDrop inside IDragHandler. I'm using the OnDragEnter to set a bool
|
I was wondering if anyone would be willing to help me figure out how I can allow CefSharp to upload Outlook Items (Attachments, Mail Items) as files into a Drop area on a website? It doesn't seem the IDragHandler responds when dragging a file onto a web page, or even the BrowserTab. I'm using the WPF Example for my testing. I have looked into https://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C I asked on Gitter, but haven't received any responses. I understand everyone's time is valuable, but I would forever be thankful for anyones help on this issue. |
here is my workaround using globalmousekeyhook to simulate using System.Collections.Generic;
using Gma.System.MouseKeyHook;
using System.Windows.Forms;
using CefSharp;
public partial class MainForm : Form
{
private IList<string> dropFiles;
private ChromiumWebBrowser Browser;
public class DragDropHandler : IDragHandler
{
public bool OnDragEnter(IWebBrowser browserControl, IBrowser browser, IDragData dragData, DragOperationsMask mask)
{
this.dropFiles = dragData.FileNames;
/*
Gotcha !!
*/
return false;
}
public void OnDraggableRegionsChanged(IWebBrowser browserControl, IBrowser browser, IList<DraggableRegion> regions)
{
}
}
public MainForm()
{
InitializeComponent();
Subscribe();
Browser = new ChromiumWebBrowser("URL");
Browser.Dock = DockStyle.Fill;
Browser.DragHandler = new DragDropHandler();
this.Controls.Add(Browser);
}
/* global mouse Drag hook */
public void Subscribe()
{
m_GlobalHook = Hook.GlobalEvents();
m_GlobalHook.MouseDragFinished += GlobalHookDragFinished;
}
private void GlobalHookDragFinished(object sender, MouseEventArgs args)
{
/*
Detect if cursor is within the bounds of a control,
so we are actually listening for any Drag Finished event
and if cursor is inside our window then this event belongs to our program
this.DesktopBounds.Contains(Cursor.Position)
*/
if (this.DesktopBounds.Contains(Cursor.Position) && this.dropFiles != null)
{
this.OnDragDrop();
/* You have to clear the results to prevent endless loop */
this.dropFiles = null;
}
else if(!this.DesktopBounds.Contains(Cursor.Position) && this.dropFiles != null )
{
/* also avoid using MessageBox becasue it will interrupt this hook and cause endless loop */
this.Text = "drop in canceld";
this.dropFiles = null;
}
}
private void Unsubscribe()
{
m_GlobalHook.MouseUpExt -= GlobalHookDragFinished;
m_GlobalHook.Dispose();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
Unsubscribe();
}
/* now you can do whaterver you want */
private void OnDragDrop()
{
/* Your code here */
}
} Gotchait only catch your files wherever a draggable region is defined in your html. otherwise default drag handling behavior fiers watch this demo but you have two choice: OR define your <body>
<div class="wrapper" ondrop="preventDrop()" ondragover="preventDrop()">
</div>
<script>
(function() {
function preventDrop(){
this.preventDefault()
}
})();
</script>
</body> i suggest using Vue.js simply because it's easier to handle everything. <template>
<div id="app" @dragover.prevent @drop="preventDrop">
</div>
</template>
<script>
export default {
methods: {
preventDrop: function(e){
e.preventDefault();
}
}
}
</script> another gotcha is that you have to clean The obtained result in |
Instead of using GlobalHooks, i am using javascript drop event where I am looking if the user is dropping a file list. If the user is dropping file list, I am invoking javascript -> CEF method to notify CEF host that it should do something with the file list captured in OnDragEnter event.
|
@ekalchev
...i was able to actually get the body drop event working and can pass it to the csharp part. Edit: forget it, i see you store the original filelist in the OnDragEnter event... That is also why you don't pass the file list in app._hostCommands.execute("fileListDropped"); |
I am not aware of any. Edit: I implemented that before Chromium allowed to see the file names of the dropped file list in javascript. I know that this is now supported in latest versions. You can send the dropped filename from javascript to C# host and compare the list with what you captured in OnDragEnter. if they match, do your stuff.. |
I'm currently intercepting the
OnDragEnter
event that CefSharp provides, but I want to handle theOnDragDrop
event which does not exist. I am already handling the form's drop drop event and I've setform.AllowDrop = true
, but since CEF intercepts the drag, I cannot handle it in the form!In
IDragHandler.OnDragEnter
:true
, then the user cannot drag anything on the browser (and I don't get the event);false
, then the user can drag a file, but CefSharp handles it internally! (and I don't get the event)So either ways I'm jammed. Is there any way to properly implement drag & drop in CefSharp, such that CefSharp/CEF does NOT do its default behaviour, and such that I get the DROP event handler. (or similar)
Alternatively, if CefSharp can use RevokeDragDrop (also here) in the
OnDragEnter
event, (in response toAllowDrop = false
) then I can handle the drop event on the form itself.Alternatively, If I can get access to these CEF flags then I can disable the internal drag/drop entirely and so fallback to the form's handling. Edit: Not possible in CEF3.
The text was updated successfully, but these errors were encountered: