Word Add-In Drag-Drop for Document

I am creating a Word add-in and allowing me to drag something from the task pane into the document, I followed the following guide: http://msdn.microsoft.com/en-us/library/office/hh780901(v=office.14).aspx

There are some real flaws using this approach.

Firstly, the transparent form of Windows (or WPF in my case) that catches the drop event is the size of the window, not the document, and RangeFromPoint always returns a value even if we are not above the document (for example, if we are above the ribbon) . Therefore, as soon as you drag something, and this form is created, no matter where you fall, it will be placed in the document. There is no elegant way to undo as soon as you start.

My question is:

Has anyone done any drag and drop work in Word Add In and found a better way to handle this than the Microsoft example you provided?

It would be nice to either use the current solution, but to know when the user is not dragging the document or that this transparent window is displayed only in the document area.

+6
source share
1 answer

I hope you already had your answer.

I have a solution for mine.

So my requirement is :

I have a custom panel containing a list, each item is a regular string. When I drag an item from a list to a document, at a specific location, I want to insert a merge field at that location. The name of the merge field is the text of the item.

At first it was simple, then I had a problem, as you describe in your question.

About the code

So there is a list, you need to handle mouseDown and mouseMove, do not worry about mouseUp.

In the mouseDown handler, I write a border; if the mouse leaves this border, drag will begin.

Then in listBox_MouseMoveHandler I check the position of the mouse to launch dragdrop. And I have to use DragDropEffects.Copy for the DoDragDrop method.

DoDragDrop((sender as ListControl).SelectedValue, DragDropEffects.Copy);

With this option, SelectedValue will be inserted into the drag position and after setting it will also be selected.

Then I just check if the selection is selected, and replace the selected text with the merge field. Of course, I dropped the choice to DoDragDrop . And this is the whole trick.

  private int _selectedItemIndex; private Rectangle dragBoxFromMouseDown; private void CustomizationForListBox(ListBox listBox) { listBox.ItemHeight = 25; listBox.DrawMode = DrawMode.OwnerDrawFixed; listBox.DrawItem += ListBox_DrawItem; listBox.MouseDoubleClick += listBox_MouseDoubleClick; listBox.MouseMove += listBox_MouseMoveHandler; listBox.MouseUp += listBox_MouseUp; listBox.MouseDown += (sender, e) => { // Handle drag/drop if (e.Button == MouseButtons.Left) { _selectedItemIndex = listBox.IndexFromPoint(e.Location); // Remember the point where the mouse down occurred. The DragSize indicates // the size that the mouse can move before a drag event should be started. Size dragSize = SystemInformation.DragSize; // Create a rectangle using the DragSize, with the mouse position being // at the center of the rectangle. dragBoxFromMouseDown = new Rectangle(new Point(eX - (dragSize.Width / 2), eY - (dragSize.Height / 2)), dragSize); } }; } private void listBox_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { // Reset the drag rectangle when the mouse button is raised. dragBoxFromMouseDown = Rectangle.Empty; } } private void listBox_MouseMoveHandler(object sender, MouseEventArgs e) { // Handle drag and drop // To check if the Mouse left button is clicked if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { // If the mouse moves outside the rectangle, start the drag. if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(eX, eY)) { // Collapse current selection, now we know nothing is selected Globals.ThisAddIn.Application.Selection.Collapse(WdCollapseDirection.wdCollapseEnd); //Start Drag Drop DoDragDrop((sender as ListControl).SelectedValue, DragDropEffects.Copy); if (_selectedItemIndex != -1) { // If the drag/drop was successful, there dropped text must be selected if (!String.IsNullOrWhiteSpace(Globals.ThisAddIn.Application.Selection.Text)) { 

// Replace the selected text with a merge field MergeFieldHelper.InsertSingleMergeField(mergeFieldInfos[_selectedItemIndex].Name); } } } } }

0
source

Source: https://habr.com/ru/post/977284/


All Articles