Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Word Add-In Drag-Drop onto document

I am creating a Word Add-In and in order to allow dragging something from a custom task pane to the document, I have followed the following guide: http://msdn.microsoft.com/en-us/library/office/hh780901(v=office.14).aspx

There are some real drawbacks using this approach.

First, the transparent Windows Form (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 aren't over the document (for instance, if we are over the Ribbon). So once you drag something and this form is created, no matter where you drop, it will be placed in the document. There is no graceful way to cancel once you've started.

My question is:

Has anyone done any work with Drag and Drop in a Word Add In, and found a better way to handle it than the supplied example by Microsoft?

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

like image 805
Kris Adams Avatar asked Oct 27 '14 15:10

Kris Adams


People also ask

Can you add a drop-down to a Word document?

To add a drop-down list to your Microsoft Word document, click the Developer tab at the top and then select Drop-Down List Content Control. This drop-down list will be empty by default and you'll have to customize it to add useful options to the text box. To customize the drop-down box, click once inside the box.

How do you insert drop-down boxes in Word?

Place your cursor in the document where you want to add the drop-down list. Go to the Developer tab and click the Drop-Down List Content Control button. You'll see the control pop into your document as a box with “Choose an item.” inside. You can then move onto setting up the list.

What is the drag-and-drop method in Word?

Techopedia Explains Drag And Drop In order to perform this action, the user must highlight the text or select the object to be moved, then press and hold down the left mouse button to grab the object. The user then drags the object to the desired location, while still holding down the mouse button.


1 Answers

Hope you already had your answer.

I got a solution for my own.

So, my requirement:

I have a custom pane, which contains a listbox, each item is a normal string. When I drag an item from the listbox into the 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.

It was simple at first, then I got a problem just like you describe in your question.

About the code

So, there is a listbox, you need to handle mouseDown and mouseMove, don't worry about mouseUp.

In mouseDown handler, I record the boundary, if the mouse moves out of that boundary, the drag will start.

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

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

With that option, SelectedValue will be inserted at the drop position, and after it is inserted, it will also be selected.

Then, I just check if selection is not empty, and replace the selected text with the merge field. Of course, I collapsed the selection before DoDragDrop. And that 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(e.X - (dragSize.Width / 2),
                                                               e.Y - (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(e.X, e.Y))
            {
                // 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); } } } } }

like image 87
vothaison Avatar answered Oct 06 '22 00:10

vothaison