private void grdViewPort_Drop(object sender, DragEventArgs e)
        {
            try
            {
                if (e.Data.GetDataPresent(TabControlParts.DRAGDROP_FORMAT))
                {
                    // Mousemove already moved it, just leave it committed
                    if (_draggingDropObject != null && _draggingDropObject.HasAddedToViewport)      // just making sure
                    {
                        #region Store Part

                        DesignPart design = new DesignPart(_options)
                        {
                            Model = _draggingDropObject.Model,
                            Part2D = _draggingDropObject.Part2D,        // could be null
                            Part3D = _draggingDropObject.Part3D
                        };

                        while (_parts.Count <= _currentLayerIndex)
                        {
                            _parts.Add(new List<DesignPart>());
                        }

                        _parts[_currentLayerIndex].Add(design);

                        #endregion

                        // Store in undo/redo
                        AddNewUndoRedoItem(new UndoRedoAddRemove[] { new UndoRedoAddRemove(true, design, _currentLayerIndex) });
                    }

                    // Let the source know.  This is useful for cases when the tab control represents specific inventory (the part is either in inventory, or
                    // on this surface)
                    TabControlParts_DragItem dragItem = (TabControlParts_DragItem)e.Data.GetData(TabControlParts.DRAGDROP_FORMAT);
                    dragItem.Dropped();

                    _draggingDropObject = null;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), _msgboxCaption, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void tabCtrl_DragDropCancelled(object sender, TabControlParts_DragItem e)
        {
            try
            {
                // Since the tabcontrol started the dragdrop, it knows when the drop failed
                // Get rid of the dragging part
                if (_draggingDropObject != null && _draggingDropObject.HasAddedToViewport)      // this will be null if they started dragging, but not over the 3D viewport
                {
                    _viewport.Children.Remove(_draggingDropObject.Model);
                }

                _draggingDropObject = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), _msgboxCaption, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void grdViewPort_PreviewDragOver(object sender, DragEventArgs e)
        {
            try
            {
                if (!e.Data.GetDataPresent(TabControlParts.DRAGDROP_FORMAT))
                {
                    e.Effects = DragDropEffects.None;
                }

                if (_draggingDropObject == null)
                {
                    TabControlParts_DragItem dragItem = (TabControlParts_DragItem)e.Data.GetData(TabControlParts.DRAGDROP_FORMAT);

                    // Since they are dragging a new part, make sure nothing is selected
                    ClearSelectedParts();

                    // Reset the snap plane
                    //ChangeDragPlane(_isVertical);
                    ChangeDragHitShape();

                    ModelVisual3D model = new ModelVisual3D();
                    model.Content = dragItem.Part3D.Model;

                    _draggingDropObject = new DraggingDropPart()
                    {
                        Part2D = dragItem.Part2D,
                        Part3D = dragItem.Part3D,
                        DragItem = dragItem,
                        Model = model,
                    };
                }

                // Move the object to where the mouse is pointing
                RayHitTestParameters clickRay = UtilityWPF.RayFromViewportPoint(_camera, _viewport, e.GetPosition(grdViewPort));
                Point3D? dragPoint = _dragHitShape.CastRay(clickRay, clickRay, clickRay, _camera, _viewport);

                if (dragPoint == null)
                {
                    _draggingDropObject.Part3D.Position = new Point3D(0, 0, 0);
                }
                else
                {
                    _draggingDropObject.Part3D.Position = dragPoint.Value;
                }

                // Since this model is in the active portion of the 3D surface, make sure the model is visible
                if (!_draggingDropObject.HasAddedToViewport)
                {
                    _viewport.Children.Add(_draggingDropObject.Model);
                    _draggingDropObject.HasAddedToViewport = true;
                }

                e.Handled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), _msgboxCaption, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }