private void DropTarget_PreviewDrop(object sender, DragEventArgs e)
        {
            object draggedItem  = e.Data.GetData(this.format.Name);
            int    indexRemoved = -1;

            if (draggedItem != null)
            {
                OutlinerNote note = draggedItem as OutlinerNote;
                if (note == null)
                {
                    RemoveInsertionAdorner();
                    RemoveDragOverMargin();
                    return;
                }

                UndoDragDrop undo = new UndoDragDrop(note);

                indexRemoved = note.Parent.SubNotes.IndexOf(note);
                note.Parent.SubNotes.Remove(note);

                // This happens when we drag an item to a later position within the same ItemsControl.
                if (indexRemoved != -1 &&
                    this.sourceItemContainer.ParentItemsControl == this.targetItemContainer && indexRemoved < this.insertionIndex)
                {
                    this.insertionIndex--;
                }
                DranDropUtilities.InsertItemInItemsControl(this.targetItemContainer, draggedItem as OutlinerNote, this.insertionIndex);
                note.Document.UndoManager.PushUndoAction(undo);

                RemoveInsertionAdorner();
                RemoveDragOverMargin();
            }
            e.Handled = true;
        }
        // Drag = mouse down + move by a certain amount
        private void DragSource_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (this.draggedData != null)
            {
                // Only drag when user moved the mouse by a reasonable amount.
                if (DranDropUtilities.IsMovementBigEnough(this.initialMousePosition, e.GetPosition(this.topWindow)))
                {
                    DataObject data = new DataObject(this.format.Name, this.draggedData);

                    // Adding events to the window to make sure dragged adorner comes up when mouse is not over a drop target.
                    bool previousAllowDrop = this.topWindow.AllowDrop;
                    this.topWindow.AllowDrop  = true;
                    this.topWindow.DragEnter += TopWindow_DragEnter;
                    this.topWindow.DragOver  += TopWindow_DragOver;
                    this.topWindow.DragLeave += TopWindow_DragLeave;

                    DragDropEffects effects = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move);

                    // Without this call, there would be a bug in the following scenario: Click on a data item, and drag
                    // the mouse very fast outside of the window. When doing this really fast, for some reason I don't get
                    // the Window leave event, and the dragged adorner is left behind.
                    // With this call, the dragged adorner will disappear when we release the mouse outside of the window,
                    // which is when the DoDragDrop synchronous method returns.
                    //RemoveDraggedAdorner();
                    //RemoveInsertionAdorner();

                    this.topWindow.AllowDrop  = previousAllowDrop;
                    this.topWindow.DragEnter -= TopWindow_DragEnter;
                    this.topWindow.DragOver  -= TopWindow_DragOver;
                    this.topWindow.DragLeave -= TopWindow_DragLeave;

                    this.draggedData = null;
                }
            }
        }
        private void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.sourceItemsControl = (ItemsControl)sender;
            TreeListView tlv = (TreeListView)this.sourceItemsControl;

            this.topWindow            = (Window)DranDropUtilities.FindAncestor(typeof(Window), this.sourceItemsControl);
            this.initialMousePosition = e.GetPosition(this.topWindow);

            Visual visual = e.OriginalSource as Visual;

            this.sourceItemContainer = DranDropUtilities.GetItemContainer(this.sourceItemsControl, visual);
            if (this.sourceItemContainer != null)
            {
                this.draggedData = sourceItemContainer.DataContext;
            }
        }
        private void DecideDropTarget(DragEventArgs e)
        {
            int    targetItemsControlCount = this.targetItemsControl.Items.Count;
            object draggedItem             = e.Data.GetData(this.format.Name);

            Visual visual = e.OriginalSource as Visual;

            targetOverItem = DranDropUtilities.FindAncestor(typeof(TreeListViewItem), visual) as TreeListViewItem;
            if (targetOverItem == null)
            {
                this.targetItemContainer = null;
                this.insertionIndex      = -1;
                e.Effects = DragDropEffects.None;
                return;
            }

            bool         newDragOverNote = false;
            OutlinerNote dragOverNote    = null;

            if (targetOverItem != null)
            {
                dragOverNote = targetOverItem.DataContext as OutlinerNote;
                if (dragOverNote != null)
                {
                    if (__DragOverNote != dragOverNote)
                    {
                        if (__DragOverNote != null)
                        {
                            __DragOverNote.DragOverNote = false;
                        }

                        newDragOverNote = true;
                    }
                }
            }

            ItemsControl parentItemsControl = targetOverItem.ParentItemsControl;

            if (parentItemsControl == null)
            {
                this.targetItemContainer = null;
                this.insertionIndex      = -1;
                e.Effects = DragDropEffects.None;
                return;
            }

            if (targetItemsControlCount > 0)
            {
                this.hasVerticalOrientation = DranDropUtilities.HasVerticalOrientation(this.targetItemsControl.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement);
                this.targetItemContainer    = parentItemsControl;
                this.insertionIndex         = parentItemsControl.ItemContainerGenerator.IndexFromContainer(targetOverItem);
                if (this.insertionIndex == -1)
                {
                    this.targetItemContainer = null;
                    this.insertionIndex      = -1;
                    e.Effects = DragDropEffects.None;
                    return;
                }

                if (IsParent(this.targetItemContainer as TreeListViewItem, this.sourceItemContainer))
                {
                    this.targetItemContainer = null;
                    this.insertionIndex      = -1;
                    e.Effects = DragDropEffects.None;
                    return;
                }

                if (newDragOverNote && dragOverNote != null)
                {
                    dragOverNote.DragOverNote = true;
                    __DragOverNote            = dragOverNote;
                }
            }
            else
            {
                this.targetItemContainer = null;
                this.insertionIndex      = 0;
            }
        }
        // DragSource

        public static MainWindow GetMainWindow(Visual visual)
        {
            return(DranDropUtilities.FindAncestor(typeof(Window), visual) as MainWindow);
        }