DragDropHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / DragDropHelper.cs / 1305376 / DragDropHelper.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------

namespace System.Activities.Presentation 
{
    using System.Diagnostics; 
    using System.Windows; 
    using System.Windows.Documents;
    using System.Windows.Media; 
    using System.Windows.Shapes;
    using System.Activities.Presentation.Hosting;
    using System.Activities.Presentation.Model;
    using System.Activities.Presentation.View; 
    using System.Windows.Threading;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization; 
    using System.Activities.Presentation.Internal.PropertyEditing;
    using System.Runtime; 


    // This is a helper class for making dragdrop inside workflow designer easy. This abstracts out te encoding formats used in the
    // DataObject that is passed on from Drag source to target. 
    public static class DragDropHelper
    { 
 
        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DragSourceProperty = 
            DependencyProperty.RegisterAttached("DragSource", typeof(UIElement), typeof(DragDropHelper), new UIPropertyMetadata(null));
        public static readonly string ModelItemDataFormat;
        public static readonly string CompositeViewFormat;
        public static readonly string CompletedEffectsFormat = "DragCompletedEffectsFormat"; 
        public static readonly string WorkflowItemTypeNameFormat = "WorkflowItemTypeNameFormat";
        public static readonly string DragAnchorPointFormat; 
 
        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
        static DragDropHelper() 
        {
            string postfix = Guid.NewGuid().ToString();
            //set per process unique data format names - this will disable possibility of trying to drag & drop operation
            //between designers in two different VS instances (use Cut-Copy-Paste for that) 
            ModelItemDataFormat = string.Format(CultureInfo.InvariantCulture, "ModelItemFormat_{0}", postfix);
            CompositeViewFormat = string.Format(CultureInfo.InvariantCulture, "CompositeViewFormat_{0}", postfix); 
            DragAnchorPointFormat = string.Format(CultureInfo.InvariantCulture, "DragAnchorFormat_{0}", postfix); 
        }
 
        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
        public static void SetCompositeView(WorkflowViewElement workflowViewElement, UIElement dragSource)
        {
            if (workflowViewElement == null) 
            {
                throw FxTrace.Exception.ArgumentNull("workflowViewElement"); 
            } 
            if (dragSource == null)
            { 
                throw FxTrace.Exception.ArgumentNull("dragSource");
            }
            workflowViewElement.SetValue(DragDropHelper.DragSourceProperty, dragSource);
        } 

        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] 
        public static UIElement GetCompositeView(WorkflowViewElement workflowViewElement) 
        {
            if (workflowViewElement == null) 
            {
                throw FxTrace.Exception.ArgumentNull("workflowViewElement");
            }
            return (UIElement)workflowViewElement.GetValue(DragDropHelper.DragSourceProperty); 
        }
 
        public static DragDropEffects DoDragMove(WorkflowViewElement draggedViewElement, Point referencePoint) 
        {
            if (draggedViewElement == null) 
            {
                throw FxTrace.Exception.ArgumentNull("draggedViewElement");
            }
            if (referencePoint == null) 
            {
                throw FxTrace.Exception.ArgumentNull("referencePoint"); 
            } 
            ModelItem draggedActivityModelItem = draggedViewElement.ModelItem;
            DataObject dataObject = new DataObject(ModelItemDataFormat, draggedActivityModelItem); 
            dataObject.SetData(CompositeViewFormat, GetCompositeView(draggedViewElement));
            dataObject.SetData(DragAnchorPointFormat, referencePoint);

            DesignerView view = draggedViewElement.Context.Services.GetService(); 
            ViewElementDragShadow dragShadow = new ViewElementDragShadow(view.scrollableContent, draggedViewElement, referencePoint, view.ZoomFactor);
 
            draggedViewElement.IsHitTestVisible = false; 
            view.BeginDragShadowTracking(dragShadow);
 
            //whenever drag drop fails - ensure getting rid of drag shadow
            try
            {
                DragDrop.DoDragDrop(GetCompositeView(draggedViewElement), dataObject, DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll | DragDropEffects.Link); 
            }
            catch 
            { 
                //let the caller handle exception
                throw; 
            }
            finally
            {
                view.EndDragShadowTracking(dragShadow); 
                draggedViewElement.IsHitTestVisible = true;
            } 
 
            return GetDragDropCompletedEffects(dataObject);
        } 

        public static bool AllowDrop(IDataObject draggedDataObject, EditingContext context, params Type[] allowedItemTypes)
        {
 
            if (draggedDataObject == null)
            { 
                throw FxTrace.Exception.ArgumentNull("draggedDataObject"); 
            }
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context");
            }
            if (allowedItemTypes == null) 
            {
                throw FxTrace.Exception.ArgumentNull("allowedItemTypes"); 
            } 
            ReadOnlyState readOnlyState = context.Items.GetValue();
            if (readOnlyState != null && readOnlyState.IsReadOnly) 
            {
                return false;
            }
            if (!AllowDrop(draggedDataObject, context)) 
            {
                return false; 
            } 
            bool allowDrop = false;
            foreach (Type type in allowedItemTypes) 
            {
                if (AllowDrop(draggedDataObject, type))
                {
                    allowDrop = true; 
                    break;
                } 
            } 
            return allowDrop;
        } 

        static bool AllowDrop(IDataObject draggedDataObject, EditingContext context)
        {
            ModelItem droppedModelItem = draggedDataObject.GetData(ModelItemDataFormat) as ModelItem; 
            if (droppedModelItem == null)
            { 
                return true; 
            }
            return ((IModelTreeItem)droppedModelItem).ModelTreeManager.Context.Equals(context); 
        }

        static bool AllowDrop(IDataObject draggedDataObject, Type allowedItemType)
        { 
            Type type = null;
            ModelItem droppedObject = draggedDataObject.GetData(ModelItemDataFormat) as ModelItem; 
            if (droppedObject == null) 
            {
                // This is an object dragged from somewhere else other than from within the designer surface 
                if (draggedDataObject.GetDataPresent(WorkflowItemTypeNameFormat))
                {
                    // This is the case where the object is dropped from the toolbox
                    string text = draggedDataObject.GetData(WorkflowItemTypeNameFormat) as string; 
                    if (!string.IsNullOrEmpty(text))
                    { 
                        type = Type.GetType(text); 
                    }
                } 
            }
            else
            {
                type = droppedObject.ItemType; 
            }
            if (type == null) 
            { 
                // This is the case where some external stuff (e.g. Recycle bin) get dragged over.
                return false; 
            }
            // This is a special case in GetDroppedObject() and replicated here.
            if (typeof(IActivityTemplateFactory).IsAssignableFrom(type))
            { 
                type = typeof(Activity);
            } 
            if (allowedItemType.IsGenericTypeDefinition) 
            {
                // We don't have inheritance relationship for GenericTypeDefinition, therefore the right check is equality 
                return allowedItemType.Equals(type.GetGenericTypeDefinition());
            }
            else
            { 
                return allowedItemType.IsAssignableFrom(type);
            } 
        } 

        public static object GetDroppedObject(DependencyObject dropTarget, DragEventArgs e, EditingContext context) 
        {
            // first try to see if the dropped object was a model item
            object droppedObject = e.Data.GetData(ModelItemDataFormat) as ModelItem;
            // could have been dropped from toolbox. 
            if (droppedObject == null)
            { 
                Type type = null; 
                if (e.Data.GetDataPresent(WorkflowItemTypeNameFormat))
                { 
                    string text = e.Data.GetData(WorkflowItemTypeNameFormat) as string;
                    if (!string.IsNullOrEmpty(text))
                    {
                        //try to use the text format to see if it holds a type name and  try to create an object out of it. 
                        type = Type.GetType(text);
                    } 
                } 
                droppedObject = GetDroppedObjectInstance(dropTarget, context, type);
            } 
            e.Handled = true;
            context.Services.GetService().WorkflowDesignerDrop();

            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, 
                    new Action(() =>
                    { 
                        context.Services.GetService().WorkflowDesignerIdleAfterDrop(); 

                    })); 


            return droppedObject;
        } 

        [SuppressMessage(FxCop.Category.Design, FxCop.Rule.DoNotCatchGeneralExceptionTypes, 
            Justification = "Any exception can be thrown from custom code. We don't want to crash VS.")] 
        [SuppressMessage("Reliability", "Reliability108",
            Justification = "Any exception can be thrown from custom code. We don't want to crash VS.")] 
        internal static object GetDroppedObjectInstance(DependencyObject dropTarget, EditingContext context, Type type)
        {
            if (type != null)
            { 
                //check if type is generic
                if (type.IsGenericTypeDefinition) 
                { 
                    type = ResolveGenericParameters(dropTarget, context, type);
                } 
            }

            object droppedObject = null;
            if (null != type) 
            {
                droppedObject = Activator.CreateInstance(type); 
                if (typeof(IActivityTemplateFactory).IsAssignableFrom(type) && type.IsClass) 
                {
                    //find parent WorkflowViewElement - in case of mouse drop, current drop target most likely is ISourceContainer 
                    if (!(dropTarget is WorkflowViewElement))
                    {
                        dropTarget = VisualTreeUtils.FindVisualAncestor(dropTarget);
                    } 
                    droppedObject = ((IActivityTemplateFactory)droppedObject).Create(dropTarget);
                } 
            } 

            return droppedObject; 
        }

        static Type ResolveGenericParameters(DependencyObject dropTarget, EditingContext context, Type type)
        { 
            // look to see if there is a DefaultTypeArgumentAttribute on it
            DefaultTypeArgumentAttribute typeArgumentAttribute = ExtensibilityAccessor.GetAttribute(type); 
            if (typeArgumentAttribute != null && typeArgumentAttribute.Type != null) 
            {
                type = type.MakeGenericType(typeArgumentAttribute.Type); 
            }
            else //require user to resolve generic arguments
            {
                ActivityTypeResolver wnd = new ActivityTypeResolver(); 
                if (null != context)
                { 
                    WindowHelperService service = context.Services.GetService(); 
                    if (null != service)
                    { 
                        service.TrySetWindowOwner(dropTarget, wnd);
                    }
                }
 
                TypeResolvingOptions dropTargetOptions = null;
                TypeResolvingOptions activityTypeOptions = null; 
 
                //try to see if the container has any customization for type resolver
                ICompositeView container = dropTarget as ICompositeView; 
                if (container != null)
                {
                    dropTargetOptions = container.DroppingTypeResolvingOptions;
                } 

                //try to see if the activity type in discourse has any customization for type resolver 
                TypeResolvingOptionsAttribute attr = WorkflowViewService.GetAttribute(type); 
                if (attr != null)
                { 
                    activityTypeOptions = attr.TypeResolvingOptions;
                }
                //if both have type resolver, try to merge them
                TypeResolvingOptions options = TypeResolvingOptions.Merge(dropTargetOptions, activityTypeOptions); 
                if (options != null)
                { 
                    wnd.Options = options; 
                }
 
                wnd.Context = context;
                wnd.EditedType = type;
                wnd.Width = 340;
                wnd.Height = 200; 
                type = (true == wnd.ShowDialog() ? wnd.ConcreteType : null);
            } 
            return type; 
        }
 
        public static ModelItem GetDraggedModelItem(DragEventArgs e)
        {
            // first try to see if the dropped object was a model item
            ModelItem draggedItem = e.Data.GetData(ModelItemDataFormat) as ModelItem; 
            return draggedItem;
        } 
 
        public static ICompositeView GetCompositeView(DragEventArgs e)
        { 
            return (ICompositeView)e.Data.GetData(CompositeViewFormat);
        }

        public static Point GetDragDropAnchorPoint(DragEventArgs e) 
        {
            Point referencePoint; 
            if (e.Data.GetDataPresent(DragAnchorPointFormat)) 
            {
                referencePoint = (Point)e.Data.GetData(DragAnchorPointFormat); 
            }
            else
            {
                referencePoint = new Point(-1, -1); 
            }
            return referencePoint; 
        } 

        public static void SetDragDropCompletedEffects(DragEventArgs e, DragDropEffects completedEffects) 
        {
            try
            {
                e.Data.SetData(CompletedEffectsFormat, completedEffects); 
            }
            catch (InvalidOperationException exception) 
            { 
                Trace.WriteLine(exception.ToString());
            } 
        }

        public static DragDropEffects GetDragDropCompletedEffects(DataObject data)
        { 
            if (data == null)
            { 
                throw FxTrace.Exception.ArgumentNull("data"); 
            }
            DragDropEffects completedEffects = DragDropEffects.None; 
            if (data.GetDataPresent(CompletedEffectsFormat))
            {
                completedEffects = (DragDropEffects)data.GetData(CompletedEffectsFormat);
            } 
            return completedEffects;
        } 
 
        internal sealed class ViewElementDragShadow : Adorner
        { 
            Rectangle content;
            double x;
            double y;
            double offsetX; 
            double offsetY;
            double scaleFactor; 
            double width; 
            double height;
            AdornerLayer layer; 
            IntPtr layerHWND;

            public ViewElementDragShadow(UIElement owner, WorkflowViewElement viewElement, Point offset, double scaleFactor) : base(owner)
            { 
                Rect bounds = VisualTreeHelper.GetDescendantBounds(viewElement);
                this.width = bounds.Width; 
                this.height = bounds.Height; 

                this.content = new Rectangle() 
                {
                    Width = this.width,
                    Height = this.height,
                    Fill = new VisualBrush(viewElement) 
                    {
                        Opacity = 0.6 
                    } 
                };
                this.offsetX = offset.X * scaleFactor; 
                this.offsetY = offset.Y * scaleFactor;
                this.Visibility = Visibility.Hidden;
                this.scaleFactor = scaleFactor;
            } 

            internal IntPtr LayerHWND 
            { 
                get { return this.layerHWND; }
                set { this.layerHWND = value; } 
            }

            internal void UpdateOffset(double deltaX, double deltaY)
            { 
                this.offsetX += deltaX;
                this.offsetY += deltaY; 
            } 

            internal void UpdatePosition(double x, double y) 
            {
                if (this.Visibility == Visibility.Hidden)
                {
                    this.Visibility = Visibility.Visible; 
                }
                double oldX = this.x; 
                double oldY = this.y; 
                this.x = x - this.offsetX;
                this.y = y - this.offsetY; 
                if (oldX != this.x || oldY != this.y)
                {
                    this.layer = this.Parent as AdornerLayer;
                    this.layer.Update(this.AdornedElement); 
                }
            } 
 
            public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
            { 
                GeneralTransformGroup result = new GeneralTransformGroup();
                result.Children.Add(new TranslateTransform(this.x, this.y ));
                result.Children.Add(new ScaleTransform(this.scaleFactor, this.scaleFactor, this.x, this.y));
                return result; 
            }
 
            protected override Visual GetVisualChild(int index) 
            {
                return this.content; 
            }

            protected override int VisualChildrenCount
            { 
                get { return 1; }
            } 
 
            protected override Size ArrangeOverride(Size finalSize)
            { 
                this.content.Arrange(new Rect(this.content.DesiredSize));
                System.Diagnostics.Debug.WriteLine("DragShadow.ArrangeOverride " + this.content.DesiredSize);
                return this.content.DesiredSize;
            } 

            protected override Size MeasureOverride(Size constraint) 
            { 
                this.content.Measure(constraint);
                System.Diagnostics.Debug.WriteLine("DragShadow.MeasureOverride " + this.content.DesiredSize); 
                return this.content.DesiredSize;
            }
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK