OleDragDropHandler.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / OleDragDropHandler.cs / 2 / OleDragDropHandler.cs

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

/* 
 */ 
namespace System.Windows.Forms.Design {
    using System.Design; 
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System;
    using System.ComponentModel.Design; 
    using System.ComponentModel.Design.Serialization; 
    using System.Windows.Forms;
    using System.Collections; 
    using System.Drawing;
    using System.Drawing.Design;
    using Microsoft.Win32;
    using System.IO; 
    using System.Windows.Forms.Design.Behavior;
    using System.Runtime.Serialization.Formatters.Binary; 
    using Microsoft.Internal.Performance; 
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters; 
    using System.Globalization;

    internal class OleDragDropHandler {
 
        // This is a bit that we stuff into the DoDragDrop
        // to indicate that the thing that is being dragged should only 
        // be allowed to be moved in the current DropTarget (e.g. parent designer). 
        // We use this for interited components that can be modified (e.g. location/size) changed
        // but not removed from their parent. 
        //
        protected const int AllowLocalMoveOnly = 0x04000000;

        private SelectionUIHandler  selectionHandler; 
        private IServiceProvider    serviceProvider;
        private IOleDragClient      client; 
 
        private bool                dragOk;
        private bool                forceDrawFrames; 
        private bool                localDrag = false;
        private bool                localDragInside = false;
        private Point               localDragOffset = Point.Empty;
        private DragDropEffects     localDragEffect; 
        private object[]            dragComps;
        private Point               dragBase = Point.Empty; 
        private static bool         freezePainting = false; 
        private static Hashtable    currentDrags;
 
        private static CodeMarkers codemarkers = CodeMarkers.Instance;

    public const string CF_CODE =  "CF_XMLCODE";
        public const string CF_COMPONENTTYPES =  "CF_COMPONENTTYPES"; 
        public const string CF_TOOLBOXITEM = "CF_NESTEDTOOLBOXITEM";
 
        public OleDragDropHandler(SelectionUIHandler selectionHandler, IServiceProvider serviceProvider, IOleDragClient client) { 
            this.serviceProvider = serviceProvider;
            this.selectionHandler = selectionHandler; 
            this.client = client;
        }

        public static string DataFormat { 
            get {
               return CF_CODE; 
            } 
        }
 
        public static string ExtraInfoFormat {
            get {
               return CF_COMPONENTTYPES;
            } 
        }
 
        public static string NestedToolboxItemFormat { 
            get {
                return CF_TOOLBOXITEM; 
            }
        }

        private IComponent GetDragOwnerComponent(IDataObject data){ 
            if (currentDrags == null || !currentDrags.Contains(data)) {
                return null; 
            } 
            return currentDrags[data] as IComponent;
        } 
        private static void AddCurrentDrag(IDataObject data, IComponent component) {
            if (currentDrags == null) {
                currentDrags = new Hashtable();
            } 
            currentDrags[data] = component;
        } 
 
        private static void RemoveCurrentDrag(IDataObject data) {
            currentDrags.Remove(data); 
        }

        internal IOleDragClient Destination {
            get { 
                return client;
            } 
        } 

        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 
        [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")]
        protected virtual bool CanDropDataObject(IDataObject dataObj) {
            if (dataObj != null) {
                if (dataObj is ComponentDataObjectWrapper) { 
                    object[] dragObjs = GetDraggingObjects(dataObj, true);
                    if (dragObjs == null) { 
                        return false; 
                    }
                    bool dropOk = true; 
                    for (int i = 0; dropOk && i < dragObjs.Length; i++) {
                        dropOk = dropOk && (dragObjs[i] is IComponent) && client.IsDropOk((IComponent)dragObjs[i]);
                    }
                    return dropOk; 
                }
                try { 
                    object serializationData = dataObj.GetData(OleDragDropHandler.DataFormat, false); 

                    if (serializationData == null) { 
                        return false;
                    }

                    IDesignerSerializationService ds = (IDesignerSerializationService)GetService(typeof(IDesignerSerializationService)); 
                    if (ds == null) {
                        return false; 
                    } 

                    ICollection objects = ds.Deserialize(serializationData); 
                    if (objects.Count > 0) {
                        bool dropOk = true;

                        foreach(object o in objects) { 
                            if (!(o is IComponent)) {
                                continue; 
                            } 
                             dropOk = dropOk && client.IsDropOk((IComponent)o);
                             if (!dropOk) break; 
                        }
                        return dropOk;
                    }
                } 
                catch (Exception ex) {
                    // we return false on any exception 
                    if (ClientUtils.IsCriticalException(ex)) { 
                        throw;
                    } 
                }
            }
            return false;
        } 

        public bool Dragging { 
            get{ 
                return localDrag;
            } 
        }

        public static bool FreezePainting {
            get { 
                return freezePainting;
            } 
        } 

        ///  
        /// 
        ///      This is the worker method of all CreateTool methods.  It is the only one
        ///      that can be overridden.
        ///  
        public IComponent[] CreateTool(ToolboxItem tool, Control parent, int x, int y, int width, int height, bool hasLocation, bool hasSize) {
            return CreateTool(tool, parent, x, y, width, height, hasLocation, hasSize, null); 
        } 

        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 
        [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")]
        public IComponent[] CreateTool(ToolboxItem tool, Control parent, int x, int y, int width, int height, bool hasLocation, bool hasSize, ToolboxSnapDragDropEventArgs e) {

            // Services we will need 
            //
            IToolboxService     toolboxSvc = (IToolboxService)GetService(typeof(IToolboxService)); 
            ISelectionService   selSvc = (ISelectionService)GetService(typeof(ISelectionService)); 
            IDesignerHost       host = (IDesignerHost)GetService(typeof(IDesignerHost));
            IComponent[]        comps = new IComponent[0]; 

            Cursor oldCursor = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
            DesignerTransaction trans = null; 

            try { 
                try { 
                    if (host != null)
                        trans = host.CreateTransaction(SR.GetString(SR.DesignerBatchCreateTool, tool.ToString())); 
                }
                catch(CheckoutException cxe) {
                    if (cxe == CheckoutException.Canceled)
                        return comps; 

                    throw cxe; 
                } 

                try { 
                    try {

                        // First check if we are currently in localization mode (i.e., language is non-default).
                        // If so, we should not permit addition of new components. This is an intentional 
                        // change from Everett - see VSWhidbey #292249.
                        if (host != null && CurrentlyLocalizing(host.RootComponent)) { 
                            IUIService uiService = (IUIService)GetService(typeof(IUIService)); 
                            if (uiService != null) {
                                uiService.ShowMessage(SR.GetString(SR.LocalizingCannotAdd)); 
                            }

                            comps = new IComponent[0];
                            return comps; 
                        }
 
                        // Create a dictionary of default values that the designer can 
                        // use to initialize a control with.
                        Hashtable defaultValues = new Hashtable(); 
                        if (parent != null) defaultValues["Parent"] = parent;

                        // adjust the location if we are in a mirrored parent. That is because the origin
                        // will then be in the upper right rather than upper left. 
                        if (parent != null  && parent.IsMirrored) {
                            x += width; 
                        } 
                        if (hasLocation) defaultValues["Location"] = new Point(x, y);
                        if (hasSize) defaultValues["Size"] = new Size(width, height); 
                        //store off extra behavior drag/drop information
                        if (e != null) defaultValues["ToolboxSnapDragDropEventArgs"] = e;

                        comps = tool.CreateComponents(host, defaultValues); 
                    }
                    catch (CheckoutException checkoutEx) { 
                        if (checkoutEx == CheckoutException.Canceled) { 
                            comps = new IComponent[0];
                        } 
                        else {
                            throw;
                        }
                    } 
                    catch (ArgumentException argumentEx) {
                        IUIService uiService = (IUIService)GetService(typeof(IUIService)); 
                        if (uiService != null) { 
                            uiService.ShowError(argumentEx);
                        } 
                    }
                    catch (Exception ex) {
                        IUIService uiService = (IUIService)GetService(typeof(IUIService));
 
                        string exceptionMessage = String.Empty;
                        if (ex.InnerException != null) { 
                            exceptionMessage = ex.InnerException.ToString(); 
                        }
                        if (String.IsNullOrEmpty(exceptionMessage)) { 
                            exceptionMessage = ex.ToString();
                        }
                        if (ex is InvalidOperationException)
                        { 
                        	exceptionMessage = ex.Message;
                        } 
                        if (uiService != null) { 
                            uiService.ShowError(ex, SR.GetString(SR.FailedToCreateComponent, tool.DisplayName, exceptionMessage));
                        } 
                        else {
                            throw;
                        }
                    } 

                    if (comps == null) { 
                        comps = new IComponent[0]; 
                    }
                } 
                finally {
                    if (toolboxSvc != null && tool.Equals(toolboxSvc.GetSelectedToolboxItem(host))) {
                        toolboxSvc.SelectedToolboxItemUsed();
                    } 
                }
            } 
            finally { 
                if (trans != null) {
                    trans.Commit(); 
                }
                Cursor.Current = oldCursor;
            }
 
            // Finally, select the newly created components.
            // 
            if (selSvc != null && comps.Length > 0) { 
                if (host != null) {
                    host.Activate(); 
                }

                ArrayList selectComps = new ArrayList(comps);
 
                for (int i = 0; i < comps.Length; i++) {
                    if (!TypeDescriptor.GetAttributes(comps[i]).Contains(DesignTimeVisibleAttribute.Yes)) { 
                        selectComps.Remove(comps[i]); 
                    }
                } 
                selSvc.SetSelectedComponents(selectComps.ToArray(), SelectionTypes.Replace);
            }

            codemarkers.CodeMarker(CodeMarkerEvent.perfFXDesignCreateComponentEnd); 
            return comps;
        } 
 
        /// 
        ///      Determines whether we are currently in localization mode - i.e., language is not (Default). 
        /// 
        private bool CurrentlyLocalizing(IComponent rootComponent) {
            if (rootComponent != null) {
                PropertyDescriptor prop = TypeDescriptor.GetProperties(rootComponent)["Language"]; 

                if (prop != null && prop.PropertyType == typeof(System.Globalization.CultureInfo)) { 
                    System.Globalization.CultureInfo ci = (System.Globalization.CultureInfo)prop.GetValue(rootComponent); 
                    if (!ci.Equals(System.Globalization.CultureInfo.InvariantCulture)) {
                        return true; 
                    }
                }
            }
 
            return false;
        } 
 
        private void DisableDragDropChildren(ICollection controls, ArrayList allowDropCache) {
            foreach(Control c in controls) { 
                if (c != null) {
                    if (c.AllowDrop) {
                        allowDropCache.Add(c);
                        c.AllowDrop = false; 
                    }
 
                    if (c.HasChildren) { 
                        DisableDragDropChildren(c.Controls, allowDropCache);
                    } 
                }
            }
        }
 
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] 
        private Point DrawDragFrames(object[] comps, 
                                     Point oldOffset, DragDropEffects oldEffect,
                                     Point newOffset, DragDropEffects newEffect, 
                                     bool drawAtNewOffset) {
            Control comp;
            Rectangle newRect = Rectangle.Empty;
            Point     tempPt = Point.Empty; 
            Control     parentControl = client.GetDesignerControl();
 
 
            if (selectionHandler == null) {
                Debug.Fail("selectionHandler should not be null"); 
                return Point.Empty;
            }

            if (comps == null) { 
                return Point.Empty;
            } 
 
            for (int i = 0; i < comps.Length; i++) {
                comp = (Control)client.GetControlForComponent(comps[i]); 

                Color backColor = SystemColors.Control;
                try {
                    backColor = comp.BackColor; 
                }
                catch(Exception ex) { 
                    if (ClientUtils.IsCriticalException(ex)) { 
                        throw;
                    } 
                }

                // If we are moving, we must make sure that the location property of the component
                // is not read only.  Otherwise, we can't move the thing. 
                //
                bool readOnlyLocation = true; 
 
                PropertyDescriptor loc = TypeDescriptor.GetProperties(comps[i])["Location"];
                if (loc != null) { 
                    readOnlyLocation = loc.IsReadOnly;
                }

                // first, undraw the old rect 
                if (!oldOffset.IsEmpty) {
                    if ((int)(oldEffect & DragDropEffects.Move) == 0 || 
                        !readOnlyLocation) { 
                        newRect = comp.Bounds;
 
                        if (drawAtNewOffset) {
                            newRect.X = oldOffset.X;
                            newRect.Y = oldOffset.Y;
                        } 
                        else {
                            newRect.Offset(oldOffset.X, oldOffset.Y); 
                        } 
                        newRect = selectionHandler.GetUpdatedRect(comp.Bounds, newRect, false);
                        DrawReversibleFrame(parentControl.Handle, newRect, backColor); 
                    }
                }

                if (!newOffset.IsEmpty) { 
                    if ((int)(oldEffect & DragDropEffects.Move) == 0 ||
                        !readOnlyLocation) { 
                        newRect = comp.Bounds; 
                        if (drawAtNewOffset) {
                            newRect.X = newOffset.X; 
                            newRect.Y = newOffset.Y;
                        }
                        else {
                            newRect.Offset(newOffset.X, newOffset.Y); 
                        }
                        newRect = selectionHandler.GetUpdatedRect(comp.Bounds, newRect, false); 
                        DrawReversibleFrame(parentControl.Handle, newRect, backColor); 
                    }
                } 
            }

            return newOffset;
        } 

        private void DrawReversibleFrame(IntPtr handle, Rectangle rectangle, Color backColor) { 
            //Bug # 71547  to make drag rect visible if any the dimensions of the control are 0 
            if (rectangle.Width == 0)
                rectangle.Width = 5; 
            if (rectangle.Height == 0)
                rectangle.Height = 5;

 
            // Copy of ControlPaint.DrawReversibleFrame, see VSWhidbey 581670
            // If ControlPaint ever gets overrloaded, we should replace the code below by calling it: 
            // ControlPaint.DrawReversibleFrame(handle, rectangle, backColor, FrameStyle.Thick); 
            // Also, remove extra code from System.Design.NativeMethods, System.Design.SafeNativeMethods
            // and System.Design.UnsafeNativeMethods 

            // ------ Duplicate code---------------------------------------------------------
            int rop2;
            Color graphicsColor; 

            if (backColor.GetBrightness() < .5) 
            { 
                rop2 = 0xA; // RasterOp.PEN.Invert().XorWith(RasterOp.TARGET);
                graphicsColor = Color.White; 
            }
            else
            {
                rop2 = 0x7; // RasterOp.PEN.XorWith(RasterOp.TARGET); 
                graphicsColor = Color.Black;
            } 
 
            IntPtr dc = UnsafeNativeMethods.GetDC(new HandleRef(null, handle));
            IntPtr pen = SafeNativeMethods.CreatePen(NativeMethods.PS_SOLID, 2, ColorTranslator.ToWin32(backColor)); 

            int prevRop2 = SafeNativeMethods.SetROP2(new HandleRef(null, dc), rop2);
            IntPtr oldBrush = SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, UnsafeNativeMethods.GetStockObject(NativeMethods.HOLLOW_BRUSH)));
            IntPtr oldPen = SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, pen)); 
            SafeNativeMethods.SetBkColor(new HandleRef(null, dc), ColorTranslator.ToWin32(graphicsColor));
            SafeNativeMethods.Rectangle(new HandleRef(null, dc), rectangle.X, rectangle.Y, rectangle.Right, rectangle.Bottom); 
 
            SafeNativeMethods.SetROP2(new HandleRef(null, dc), prevRop2);
            SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, oldBrush)); 
            SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, oldPen));

            if (pen != IntPtr.Zero)
            { 
                SafeNativeMethods.DeleteObject(new HandleRef(null, pen));
            } 
 
            UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, dc));
            // ------ Duplicate code--------------------------------------------------------- 
        }

        public bool DoBeginDrag(object[] components, SelectionRules rules, int initialX, int initialY) {
            // if we're in a sizing operation, or the mouse isn't down, don't do this! 
            if ((rules & SelectionRules.AllSizeable) != SelectionRules.None || Control.MouseButtons == MouseButtons.None) {
                return true; 
            } 

 
            Control c = (Control)client.GetDesignerControl();

            localDrag = true;
            localDragInside = false; 

            dragComps = components; 
            dragBase = new Point(initialX, initialY); 
            localDragOffset = Point.Empty;
            Point basePt = c.PointToClient(new Point(initialX,initialY)); 

            DragDropEffects allowedEffects = DragDropEffects.Copy | DragDropEffects.None | DragDropEffects.Move;

            // check to see if any of the components are inherhited. if so, don't allow them to be moved. 
            // We replace DragDropEffects.Move with a local bit called AllowLocalMoveOnly which means it
            // can be moved around on the current dropsource/target, but not to another target.  Since only 
            // we understand this bit, other drop targets will not allow the move to occur 
            //
            for (int i = 0; i < components.Length; i++) { 
                InheritanceAttribute attr = (InheritanceAttribute)TypeDescriptor.GetAttributes(components[i])[typeof(InheritanceAttribute)];

                if (!attr.Equals(InheritanceAttribute.NotInherited) && !attr.Equals(InheritanceAttribute.InheritedReadOnly)) {
                    allowedEffects &= ~DragDropEffects.Move; 
                    allowedEffects |= (DragDropEffects)AllowLocalMoveOnly;
                } 
            } 

            DataObject data = new ComponentDataObjectWrapper(new ComponentDataObject(client, serviceProvider, components, initialX, initialY)); 

            // We make sure we're painted before we start the drag.  Then, we disable window painting to
            // ensure that the drag can proceed without leaving artifacts lying around.  We should be caling LockWindowUpdate,
            // but that causes a horrible flashing because GDI+ uses direct draw. 
            //
            NativeMethods.MSG msg = new NativeMethods.MSG(); 
            while (NativeMethods.PeekMessage(ref msg, IntPtr.Zero, NativeMethods.WM_PAINT, NativeMethods.WM_PAINT, NativeMethods.PM_REMOVE)) { 
                NativeMethods.TranslateMessage(ref msg);
                NativeMethods.DispatchMessage(ref msg); 
            }

            // don't do any new painting...
            bool oldFreezePainting = freezePainting; 

            // asurt 90345 -- this causes some subtle bugs, so i'm turning it off to see if we really need it, and if we do 
            // if we can find a better way. 
            //
            //freezePainting = true; 

            AddCurrentDrag(data, client.Component);

            // Walk through all the children recursively and disable drag-drop 
            // for each of them. This way, we will not accidentally try to drop
            // ourselves into our own children. 
            // 
            ArrayList allowDropChanged = new ArrayList();
            foreach(object comp in components) { 
                Control ctl = comp as Control;
                if (ctl != null && ctl.HasChildren) {
                    DisableDragDropChildren(ctl.Controls, allowDropChanged);
                } 
            }
 
            DragDropEffects effect = DragDropEffects.None; 
            IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
            DesignerTransaction trans = null; 
            if (host != null) {
                trans = host.CreateTransaction(SR.GetString(SR.DragDropDragComponents, components.Length));
            }
            try { 
                effect = c.DoDragDrop(data, allowedEffects);
                if (trans != null) { 
                    trans.Commit(); 
                }
            } 
            finally {
                RemoveCurrentDrag(data);

                // Reset the AllowDrop for the components being dragged. 
                //
                foreach(Control ctl in allowDropChanged) { 
                    ctl.AllowDrop = true; 
                }
 
                freezePainting = oldFreezePainting;

                if (trans != null) {
                    ((IDisposable)trans).Dispose(); 
                }
            } 
 
            bool isMove = ((int)(effect & DragDropEffects.Move)) != 0 || ((int)((int)effect & AllowLocalMoveOnly)) != 0;
 
            // since the EndDrag will clear this
            bool isLocalMove = isMove && localDragInside;

            ISelectionUIService selectionUISvc = (ISelectionUIService)GetService(typeof(ISelectionUIService)); 
            Debug.Assert(selectionUISvc != null, "Unable to get selection ui service when adding child control");
 
            if (selectionUISvc != null) { 
                // We must check to ensure that UI service is still in drag mode.  It is
                // possible that the user hit escape, which will cancel drag mode. 
                //
                if (selectionUISvc.Dragging) {
                    // cancel the drag if we aren't doing a local move
                    selectionUISvc.EndDrag(!isLocalMove); 
                }
 
            } 

            if (!localDragOffset.IsEmpty && effect != DragDropEffects.None) { 

                DrawDragFrames(dragComps, localDragOffset, localDragEffect,
                               Point.Empty, DragDropEffects.None, false);
            } 

            localDragOffset = Point.Empty; 
            dragComps = null; 
            localDrag = localDragInside = false;
            dragBase = Point.Empty; 

            /*if (!isLocalMove && isMove){
                IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
                IUndoService  undoService = (IUndoService)GetService(typeof(IUndoService)); 
                IActionUnit unit = null;
 
                if (host != null) { 
                    DesignerTransaction trans = host.CreateTransaction("Drag/drop");
                    try{ 
                        // delete the components
                        try{
                            for (int i = 0; i < components.Length; i++){
                               if (components[i] is IComponent){ 
                                  if (undoService != null){
                                      unit = new CreateControlActionUnit(host, (IComponent)components[i], true); 
                                  } 
                                  host.DestroyComponent((IComponent)components[i]);
                                  if (undoService != null){ 
                                       undoService.AddAction(unit, false);
                                  }
                               }
                            } 
                        }catch(CheckoutException ex){
                            if (ex != CheckoutException.Canceled){ 
                                throw ex; 
                            }
                        } 
                    }
                    finally{
                        trans.Commit();
                    } 
                }
            }*/ 
 
            return false;
        } 

        public void DoEndDrag(object[] components, bool cancel) {
            dragComps = null;
            localDrag = false; 
            localDragInside = false;
        } 
 
        public void DoOleDragDrop(DragEventArgs de) {
            // ASURT 43757: By the time we come here, it means that the user completed the drag-drop and 
            // we compute the new location/size of the controls if needed and set the property values.
            // We have to stop freezePainting right here, so that controls can get a chance to validate
            // their new rects.
            // 
            freezePainting = false;
 
            if (selectionHandler == null) { 
                Debug.Fail("selectionHandler should not be null");
                de.Effect = DragDropEffects.None; 
                return;
            }

            // make sure we've actually moved 
            if ((localDrag && de.X == dragBase.X && de.Y == dragBase.Y) ||
                de.AllowedEffect == DragDropEffects.None || 
                (!localDrag && !dragOk)) { 

                de.Effect = DragDropEffects.None; 
                return;
            }

            bool localMoveOnly = ((int)((int)de.AllowedEffect & AllowLocalMoveOnly)) != 0 && localDragInside; 

            // if we are dragging inside the local dropsource/target, and and AllowLocalMoveOnly flag is set, 
            // we just consider this a normal move. 
            //
            bool moveAllowed = (de.AllowedEffect & DragDropEffects.Move) != DragDropEffects.None || localMoveOnly; 
            bool copyAllowed = (de.AllowedEffect & DragDropEffects.Copy) != DragDropEffects.None;

            if ((de.Effect & DragDropEffects.Move) != 0 && !moveAllowed) {
                // Try copy instead? 
                de.Effect = DragDropEffects.Copy;
            } 
 
            // make sure the copy is allowed
            if ((de.Effect & DragDropEffects.Copy) != 0 && !copyAllowed) { 
                // if copy isn't allowed, don't do anything

                de.Effect = DragDropEffects.None;
                return; 
            }
 
            if (localMoveOnly && (de.Effect & DragDropEffects.Move) != 0) { 
               de.Effect |= (DragDropEffects)AllowLocalMoveOnly | DragDropEffects.Move;
            } 
            else if ((de.Effect & DragDropEffects.Copy) != 0) {
                de.Effect = DragDropEffects.Copy;
            }
 
            if (forceDrawFrames || localDragInside) {
                // undraw the drag rect 
                localDragOffset = DrawDragFrames(dragComps, localDragOffset, localDragEffect, 
                                                 Point.Empty, DragDropEffects.None, forceDrawFrames);
                forceDrawFrames = false; 
            }

            Cursor oldCursor = Cursor.Current;
 
            try {
                Cursor.Current = Cursors.WaitCursor; 
 
                if (dragOk || (localDragInside && de.Effect == DragDropEffects.Copy)) {
 
                    // add em to this parent.
                    IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
                    IContainer container = host.RootComponent.Site.Container;
 
                    object[] components;
                    IDataObject dataObj = de.Data; 
                    bool updateLocation = false; 

                    if (dataObj is ComponentDataObjectWrapper) { 
                        dataObj = ((ComponentDataObjectWrapper)dataObj).InnerData;
                        ComponentDataObject cdo = (ComponentDataObject)dataObj;

                        // if we're moving ot a different container, do a full serialization 
                        // to make sure we pick up design time props, etc.
                        // 
                        IComponent dragOwner = GetDragOwnerComponent(de.Data); 
                        bool newContainer = dragOwner == null || client.Component == null || dragOwner.Site.Container != client.Component.Site.Container;
                        bool collapseChildren = false; 
                        if (de.Effect == DragDropEffects.Copy || newContainer) {
                            // this causes new elements to be created
                            //
                            cdo.Deserialize(serviceProvider, (int)(de.Effect & DragDropEffects.Copy) == 0); 
                        }
                        else { 
                            collapseChildren = true; 
                        }
                        updateLocation = true; 
                        components = cdo.Components;

                        if (collapseChildren) {
                            components = GetTopLevelComponents(components); 
                        }
 
                    } 
                    else {
 
                        object serializationData = dataObj.GetData(OleDragDropHandler.DataFormat, true);

                        if (serializationData == null) {
                            Debug.Fail("data object didn't return any data, so how did we allow the drop?"); 
                            components = new IComponent[0];
                        } 
                        else { 
                            dataObj = new ComponentDataObject(client,  serviceProvider, serializationData);
                            components = ((ComponentDataObject)dataObj).Components; 
                            updateLocation = true;
                        }
                    }
 
                    // now we need to offset the components locations from the drop mouse
                    // point to the parent, since their current locations are relative 
                    // the the mouse pointer 
                    if (components != null && components.Length > 0) {
 
                        Debug.Assert(container != null, "Didn't get a container from the site!");
                        string name;
                        IComponent comp = null;
 
                        DesignerTransaction trans = null;
 
                        try { 
                            trans = host.CreateTransaction(SR.GetString(SR.DragDropDropComponents));
                            if (!localDrag) { 
                                host.Activate();
                            }

                            ArrayList selectComps = new ArrayList(); 

 
                            for (int i = 0; i < components.Length; i++) { 

                                comp = components[i] as IComponent; 

                                if (comp == null) {
                                    comp = null;
                                    continue; 
                                }
 
                                try { 
                                    name = null;
                                    if (comp.Site != null) { 
                                        name = comp.Site.Name;
                                    }

                                    Control oldDesignerControl = null; 
                                    if (updateLocation) {
 
                                        oldDesignerControl = client.GetDesignerControl(); 
                                        NativeMethods.SendMessage(oldDesignerControl.Handle, NativeMethods.WM_SETREDRAW, 0, 0);
                                    } 

                                    Point dropPt = client.GetDesignerControl().PointToClient(new Point(de.X, de.Y));

                                    // First check if the component we are dropping have a TrayLocation, and if so, use it 
                                    PropertyDescriptor loc = TypeDescriptor.GetProperties(comp)["TrayLocation"];
                                    if (loc == null) { 
                                        // it didn't, so let's check for the regular Location 
                                        loc = TypeDescriptor.GetProperties(comp)["Location"];
                                    } 

                                    if (loc != null && !loc.IsReadOnly) {
                                        Rectangle bounds = new Rectangle();
                                        Point pt = (Point)loc.GetValue(comp); 
                                        bounds.X = dropPt.X + pt.X;
                                        bounds.Y = dropPt.Y + pt.Y; 
                                        bounds = selectionHandler.GetUpdatedRect(Rectangle.Empty, bounds, false); 
                                    }
 
                                    if (!client.AddComponent(comp, name, false)) {
                                        // this means that we just moved the control
                                        // around in the same designer.
 
                                        de.Effect = DragDropEffects.None;
                                    } 
                                    else { 
                                        // make sure the component was added to this client
                                        if (client.GetControlForComponent(comp) == null) { 
                                           updateLocation = false;
                                        }
                                    }
 
                                    if (updateLocation) {
 
                                        ParentControlDesigner parentDesigner = client as ParentControlDesigner; 
                                        if (parentDesigner != null) {
                                            Control c = client.GetControlForComponent(comp); 
                                            dropPt = parentDesigner.GetSnappedPoint(c.Location);
                                            c.Location = dropPt;
                                        }
                                    } 

                                    if (oldDesignerControl != null) { 
                                        //((ComponentDataObject)dataObj).ShowControls(); 
                                        NativeMethods.SendMessage(oldDesignerControl.Handle, NativeMethods.WM_SETREDRAW, 1, 0);
                                        oldDesignerControl.Invalidate(true); 
                                    }

                                    if (TypeDescriptor.GetAttributes(comp).Contains(DesignTimeVisibleAttribute.Yes)) {
                                         selectComps.Add(comp); 
                                    }
                                } 
                                catch (CheckoutException ceex) { 
                                    if (ceex == CheckoutException.Canceled) {
                                        break; 
                                    }
                                    throw;
                                }
                            } 

                            if (host != null) { 
                                 host.Activate(); 
                            }
 
                            // select the newly added components
                            ISelectionService selService = (ISelectionService)GetService(typeof(ISelectionService));

                            selService.SetSelectedComponents((object[])selectComps.ToArray(typeof(IComponent)), SelectionTypes.Replace); 
                            localDragInside = false;
                        } 
                        finally { 
                            if (trans != null)
                                trans.Commit(); 
                        }
                    }
                }
 

                if (localDragInside) { 
                    ISelectionUIService selectionUISvc = (ISelectionUIService)GetService(typeof(ISelectionUIService)); 
                    Debug.Assert(selectionUISvc != null, "Unable to get selection ui service when adding child control");
 
                    if (selectionUISvc != null) {
                        // We must check to ensure that UI service is still in drag mode.  It is
                        // possible that the user hit escape, which will cancel drag mode.
                        // 
                        if (selectionUISvc.Dragging && moveAllowed) {
                            Rectangle offset = new Rectangle(de.X - dragBase.X, de.Y - dragBase.Y, 0, 0); 
                            selectionUISvc.DragMoved(offset); 
                        }
 
                    }

                }
                dragOk = false; 
            }
            finally { 
               Cursor.Current = oldCursor; 
            }
        } 

        public void DoOleDragEnter(DragEventArgs de) {
            /*
            this causes focus rects to be drawn, which we don't want to happen. 

            Control dragHost = client.GetDesignerControl(); 
 
            if (dragHost != null && dragHost.CanSelect) {
                dragHost.Focus(); 
            }*/

            if (!localDrag && CanDropDataObject(de.Data) && de.AllowedEffect != DragDropEffects.None) {
 
                if (!client.CanModifyComponents) {
                    return; 
                } 
                dragOk = true;
 
                // this means it's not us doing the drag
                if ((int)(de.KeyState & NativeMethods.MK_CONTROL) != 0 && (de.AllowedEffect & DragDropEffects.Copy) != (DragDropEffects)0) {
                    de.Effect = DragDropEffects.Copy;
                } 
                else if ((de.AllowedEffect & DragDropEffects.Move) != (DragDropEffects)0) {
                    de.Effect = DragDropEffects.Move; 
                } 
                else {
 
                    de.Effect = DragDropEffects.None;
                    return;
                }
 
            }
            else if (localDrag && de.AllowedEffect != DragDropEffects.None) { 
                localDragInside = true; 
                if ((int)(de.KeyState & NativeMethods.MK_CONTROL) != 0 && (de.AllowedEffect & DragDropEffects.Copy) != (DragDropEffects)0 && client.CanModifyComponents) {
                    de.Effect = DragDropEffects.Copy; 
                }

                bool localMoveOnly = ((int)((int)de.AllowedEffect & AllowLocalMoveOnly)) != 0 && localDragInside;
 
                if (localMoveOnly) {
                    de.Effect |= (DragDropEffects)AllowLocalMoveOnly; 
                } 

                if ((de.AllowedEffect & DragDropEffects.Move) != (DragDropEffects)0) { 
                    de.Effect |= DragDropEffects.Move;
                }
            }
            else { 

                de.Effect = DragDropEffects.None; 
            } 
        }
 
        public void DoOleDragLeave() {

            if (localDrag || forceDrawFrames) {
                localDragInside = false; 
                localDragOffset = DrawDragFrames(dragComps, localDragOffset, localDragEffect,
                                                 Point.Empty, DragDropEffects.None, forceDrawFrames); 
 
                if (forceDrawFrames && dragOk) {
                    dragBase = Point.Empty; 
                    dragComps = null;
                }
                forceDrawFrames = false;
            } 
            dragOk = false;
        } 
 
        public void DoOleDragOver(DragEventArgs de) {
            Debug.WriteLineIf(CompModSwitches.DragDrop.TraceInfo, "\tOleDragDropHandler.OnDragOver: " + de.ToString()); 
            if (!localDrag && !dragOk) {
                de.Effect = DragDropEffects.None;
                return;
            } 

            bool copy = (int)(de.KeyState & NativeMethods.MK_CONTROL) != 0 && (de.AllowedEffect & DragDropEffects.Copy) != (DragDropEffects)0 && client.CanModifyComponents; 
 
            // we pretend AllowLocalMoveOnly is a normal move when we are over the originating container.
            // 
            bool localMoveOnly = ((int)((int)de.AllowedEffect & AllowLocalMoveOnly)) != 0 && localDragInside;
            bool move = (de.AllowedEffect & DragDropEffects.Move) != (DragDropEffects)0 || localMoveOnly;

            if ((copy || move) && (localDrag || forceDrawFrames)) { 
               // draw the shadow rects.
               Point newOffset = Point.Empty; 
               Point convertedPoint = client.GetDesignerControl().PointToClient(new Point(de.X, de.Y)); 

               if (forceDrawFrames) { 
                  newOffset = convertedPoint;
               }
               else {
                  newOffset = new Point(de.X - dragBase.X, de.Y - dragBase.Y); 
               }
 
               // 96845 -- only allow drops on the client area 
               //
               if (!client.GetDesignerControl().ClientRectangle.Contains(convertedPoint)) { 
                   copy = false;
                   move = false;
                   newOffset = localDragOffset;
               } 

               if (newOffset != localDragOffset) { 
                  Debug.WriteLineIf(CompModSwitches.DragDrop.TraceInfo, "\tParentControlDesigner.OnDragOver: " + de.ToString()); 
                  DrawDragFrames(dragComps, localDragOffset, localDragEffect,
                                 newOffset, de.Effect, forceDrawFrames); 
                  localDragOffset = newOffset;
                  localDragEffect = de.Effect;
               }
            } 

 
 
            if (copy) {
                de.Effect = DragDropEffects.Copy; 
            }
            else if (move) {
                de.Effect = DragDropEffects.Move;
            } 
            else {
                de.Effect = DragDropEffects.None; 
            } 

            if (localMoveOnly) { 
               de.Effect |= (DragDropEffects)AllowLocalMoveOnly;
            }
        }
 
        public void DoOleGiveFeedback(GiveFeedbackEventArgs e) {
            if (selectionHandler == null) { 
                Debug.Fail("selectionHandler should not be null"); 
            }
 
            e.UseDefaultCursors = ((!localDragInside && !forceDrawFrames) || ((e.Effect & (DragDropEffects.Copy)) != 0)) || e.Effect == DragDropEffects.None;
            if (!e.UseDefaultCursors && selectionHandler != null) {
                selectionHandler.SetCursor();
            } 
        }
 
        private object[] GetDraggingObjects(IDataObject dataObj, bool topLevelOnly) { 
            object[] components = null;
 
            if (dataObj is ComponentDataObjectWrapper) {
                dataObj = ((ComponentDataObjectWrapper)dataObj).InnerData;
                ComponentDataObject cdo = (ComponentDataObject)dataObj;
 
                components = cdo.Components;
            } 
 
            if (!topLevelOnly || components == null) {
                return components; 
            }

            return GetTopLevelComponents(components);
        } 

        public object[] GetDraggingObjects(IDataObject dataObj) { 
            return GetDraggingObjects(dataObj, false); 
        }
 
        public object[] GetDraggingObjects(DragEventArgs de) {
            return GetDraggingObjects(de.Data);
        }
 
        private object[] GetTopLevelComponents(ICollection comps) {
            // Filter the top-level components. 
            // 
            if (!(comps is IList)) {
                comps = new ArrayList(comps); 
            }
            IList compList = (IList)comps;
            ArrayList topLevel = new ArrayList();
            foreach(object comp in compList) { 
                Control c = comp as Control;
                if (c == null && comp != null) { 
                    topLevel.Add(comp); 
                }
                else if (c != null){ 
                    if (c.Parent == null || !compList.Contains(c.Parent)) {
                        topLevel.Add(comp);
                    }
                } 
            }
 
            return topLevel.ToArray(); 
        }
 
        protected object GetService(Type t) {
            return serviceProvider.GetService(t);
        }
 
        protected virtual void OnInitializeComponent(IComponent comp, int x, int y, int width, int height, bool hasLocation, bool hasSize) {
        } 
 
        // just so we can recognize the ones we create
        protected class ComponentDataObjectWrapper: System.Windows.Forms.DataObject{ 
            ComponentDataObject innerData;

            public ComponentDataObjectWrapper(ComponentDataObject dataObject) : base((IDataObject)dataObject){
                innerData = dataObject; 
            }
 
            public ComponentDataObject InnerData{ 
                get{
                    return innerData; 
                }
            }
        }
 
        protected class ComponentDataObject : System.Windows.Forms.IDataObject {
            private IServiceProvider  serviceProvider; 
            private object[]          components; 

            private Stream                  serializationStream; 
            private object                  serializationData;
            private int                     initialX;
            private int                     initialY;
            private IOleDragClient          dragClient; 
            private CfCodeToolboxItem       toolboxitemdata;
 
            public ComponentDataObject(IOleDragClient dragClient, IServiceProvider sp, object[] comps, int x, int y) { 
                this.serviceProvider = sp;
                this.components = GetComponentList(comps, null, -1); 
                this.initialX = x;
                this.initialY = y;
                this.dragClient = dragClient;
            } 

            public ComponentDataObject(IOleDragClient dragClient, IServiceProvider sp, object serializationData) { 
                this.serviceProvider = sp; 
                this.serializationData = serializationData;
                this.dragClient = dragClient; 
            }

            private Stream SerializationStream {
                get { 
                    if (serializationStream == null && Components != null) {
                        IDesignerSerializationService ds = (IDesignerSerializationService)serviceProvider.GetService(typeof(IDesignerSerializationService)); 
                        if (ds != null) { 

                            object[] comps = new object[components.Length]; 
                            for (int i = 0; i < components.Length; i++) {
                                Debug.Assert(components[i] is IComponent, "Item " + components[i].GetType().Name + " is not an IComponent");
                                comps[i] = (IComponent)components[i];
                            } 

                            object sd = ds.Serialize(comps); 
                            serializationStream = new MemoryStream(); 
                            BinaryFormatter formatter = new BinaryFormatter();
                            formatter.Serialize(serializationStream, sd); 
                            serializationStream.Seek(0, SeekOrigin.Begin);
                        }
                    }
                    return serializationStream; 
                }
            } 
 

            public object[] Components{ 
                get{
                    if (components == null && (serializationStream != null || serializationData != null)) {
                        Deserialize(null, false);
                        if (components == null) { 
                            return new object[0];
                        } 
                    } 
                    return(object[])components.Clone();
                } 
            }

            /// 
            /// computes the IDataObject which constitutes this whole toolboxitem for storage in the toolbox. 
            /// 
            private CfCodeToolboxItem NestedToolboxItem { 
                get { 
                    if (toolboxitemdata == null) {
                        toolboxitemdata = new CfCodeToolboxItem(this.GetData(OleDragDropHandler.DataFormat)); 
                    }
                    return toolboxitemdata;
                }
            } 

            ///  
            ///  
            ///     Used to retrieve the selection for a copy.  The default implementation
            ///     retrieves the current selection. 
            /// 
            private object[] GetComponentList(object[] components, ArrayList list, int index) {

                if (serviceProvider == null) { 
                    return components;
                } 
 
                ISelectionService selSvc = (ISelectionService)this.serviceProvider.GetService(typeof(ISelectionService));
 
                if (selSvc == null) {
                    return components;
                }
 
                ICollection selectedComponents;
                if (components == null) 
                    selectedComponents = selSvc.GetSelectedComponents(); 
                else
                    selectedComponents = new ArrayList(components); 


                IDesignerHost host = (IDesignerHost)serviceProvider.GetService(typeof(IDesignerHost));
                if (host != null) { 
                    ArrayList copySelection = new ArrayList();
                    foreach (IComponent comp in selectedComponents) { 
                        copySelection.Add(comp); 
                        GetAssociatedComponents(comp, host, copySelection);
                    } 
                    selectedComponents = copySelection;
                }
                object[] comps = new object[selectedComponents.Count];
                selectedComponents.CopyTo(comps, 0); 
                return comps;
            } 
 
            private void GetAssociatedComponents(IComponent component, IDesignerHost host, ArrayList list) {
                ComponentDesigner designer = host.GetDesigner(component) as ComponentDesigner; 
                if (designer == null) {
                    return;
                }
 
                foreach (IComponent childComp in designer.AssociatedComponents) {
                    list.Add(childComp); 
                    GetAssociatedComponents(childComp, host, list); 
                }
            } 

            public virtual object GetData(string format) {
                return GetData(format, false);
            } 

            public virtual object GetData(string format, bool autoConvert) { 
                if (format.Equals(OleDragDropHandler.DataFormat)) { 
                    BinaryFormatter formatter = new BinaryFormatter();
                    SerializationStream.Seek(0, SeekOrigin.Begin); 
                    return formatter.Deserialize(this.SerializationStream);
                }
                else if (format.Equals(OleDragDropHandler.NestedToolboxItemFormat)){
                    NestedToolboxItem.SetDisplayName(); 
                    return NestedToolboxItem;
                } 
                return null; 
            }
 
            public virtual object GetData(Type t) {
                return GetData(t.FullName);
            }
 
            /// 
            ///  
            ///     If the there is data store in the data object associated with 
            ///     format this will return true.
            /// 
            /// 
            public bool GetDataPresent(string format, bool autoConvert){
                return Array.IndexOf(GetFormats(), format) != -1;
            } 

            ///  
            ///  
            ///     If the there is data store in the data object associated with
            ///     format this will return true. 
            ///
            /// 
            public bool GetDataPresent(string format){
                return GetDataPresent(format, false); 
            }
 
            ///  
            /// 
            ///     If the there is data store in the data object associated with 
            ///     format this will return true.
            ///
            /// 
            public bool GetDataPresent(Type format){ 
                return GetDataPresent(format.FullName, false);
            } 
 
            /// 
            ///  
            ///     Retrieves a list of all formats stored in this data object.
            ///
            /// 
            public string[] GetFormats(bool autoConvert){ 
                return GetFormats();
            } 
 
            /// 
            ///  
            ///     Retrieves a list of all formats stored in this data object.
            ///
            /// 
            public string[] GetFormats(){ 
                return new string[] { OleDragDropHandler.NestedToolboxItemFormat, OleDragDropHandler.DataFormat, DataFormats.Serializable, OleDragDropHandler.ExtraInfoFormat };
            } 
 

            public void Deserialize(IServiceProvider serviceProvider, bool removeCurrentComponents) { 

                if (serviceProvider == null) {
                    serviceProvider = this.serviceProvider;
                } 

                IDesignerSerializationService ds = (IDesignerSerializationService)serviceProvider.GetService(typeof(IDesignerSerializationService)); 
                IDesignerHost host = null; 
                DesignerTransaction trans = null;
 
                try {
                    if (serializationData == null) {
                        BinaryFormatter formatter = new BinaryFormatter();
                        serializationData = formatter.Deserialize(SerializationStream); 
                    }
 
                    if (removeCurrentComponents && components != null) { 
                        foreach (IComponent removeComp in components) {
 
                            if (host == null && removeComp.Site != null) {
                                host = (IDesignerHost)removeComp.Site.GetService(typeof(IDesignerHost));
                                if (host != null) {
                                    trans = host.CreateTransaction(SR.GetString(SR.DragDropMoveComponents, components.Length)); 
                                }
                            } 
                            if (host != null) { 
                                host.DestroyComponent(removeComp);
                            } 
                        }
                        components = null;
                    }
 
                    ICollection objects = ds.Deserialize(serializationData);
                    components = new IComponent[objects.Count]; 
                    IEnumerator e = objects.GetEnumerator(); 
                    int idx = 0;
 
                    while(e.MoveNext()) {
                        components[idx++] = (IComponent)e.Current;
                    }
 
                    // only do top-level components here,
                    // because other are already parented. 
                    // otherwise, when we process these 
                    // components it's too hard to know what we
                    // should be reparenting. 
                    ArrayList topComps = new ArrayList();
                    for (int i = 0; i < components.Length; i++) {

                        if (components[i] is Control) { 
                           Control c = (Control)components[i];
                           if (c.Parent == null) { 
                               topComps.Add(components[i]); 
                           }
                        } 
                        else {
                           topComps.Add(components[i]);
                        }
                    } 

                    components = (object[])topComps.ToArray(); 
 
                }
                finally { 
                    if (trans != null) {
                        trans.Commit();
                    }
                } 
            }
 
            ///  
            /// 
            ///     Sets the data to be associated with the specific data format. For 
            ///     a listing of predefined formats see System.Windows.Forms.DataFormats.
            ///
            /// 
            public void SetData(string format, bool autoConvert, object data){ 
                SetData(format, data);
            } 
 
            /// 
            ///  
            ///     Sets the data to be associated with the specific data format. For
            ///     a listing of predefined formats see System.Windows.Forms.DataFormats.
            ///
            ///  
            public void SetData(string format, object data){
                throw new Exception(SR.GetString(SR.DragDropSetDataError)); 
            } 

            ///  
            /// 
            ///     Sets the data to be associated with the specific data format.
            ///
            ///  
            public void SetData(Type format, object data){
                SetData(format.FullName, data); 
            } 

            ///  
            /// 
            ///     Stores data in the data object. The format assumed is the
            ///     class of data
            /// 
            /// 
            public void SetData(object data){ 
                SetData(data.GetType(), data); 
            }
 
        }

        [Serializable]
        internal class CfCodeToolboxItem : ToolboxItem { 
            private object serializationData;
            private static int template = 0; 
            bool displaynameset = false; 

            public CfCodeToolboxItem(object serializationData) : base() { 
                this.serializationData = serializationData;
            }

 
            [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
            private CfCodeToolboxItem(SerializationInfo info, StreamingContext context) { 
                Deserialize(info, context); 
            }
 
            /// 
            /// 
            public void SetDisplayName() {
                if (!displaynameset) { 
                    displaynameset = true;
                    this.DisplayName = "Template" + (++template).ToString(CultureInfo.CurrentCulture); 
                } 
            }
 
            /// 
            /// Saves the state of this  to
            ///    the specified serialization info.
            ///  
            protected override void Serialize(SerializationInfo info, StreamingContext context) {
                base.Serialize(info, context); 
                if (serializationData != null) { 
                    info.AddValue("CfCodeToolboxItem.serializationData", serializationData);
                } 
            }

            /// 
            /// Loads the state of this  
            /// from the stream.
            ///  
            protected override void Deserialize(SerializationInfo info, StreamingContext context) { 
                base.Deserialize(info, context);
 
                foreach (SerializationEntry entry in info) {
                    if (entry.Name == "CfCodeToolboxItem.serializationData") {
                        serializationData = entry.Value;
                        break; 
                    }
                } 
            } 

            protected override IComponent[] CreateComponentsCore(IDesignerHost host, IDictionary defaultValues) { 
                IDesignerSerializationService ds = (IDesignerSerializationService)host.GetService(typeof(IDesignerSerializationService));
                if (ds == null) {
                    return null;
                } 

                // Deserialize to components collection 
                // 
                ICollection objects = ds.Deserialize(serializationData);
                ArrayList components = new ArrayList(); 
                foreach(object obj in objects) {
                    if (obj != null && obj is IComponent) {
                        components.Add(obj);
                    } 
                }
                IComponent[] componentsArray = new IComponent[components.Count]; 
                components.CopyTo(componentsArray, 0); 

 
                ArrayList trayComponents = null;

                // Parent and locate each Control
                // 
                if (defaultValues == null) defaultValues = new Hashtable();
                Control parentControl = parentControl = defaultValues["Parent"] as Control; 
                if (parentControl != null) { 
                    ParentControlDesigner parentControlDesigner = host.GetDesigner(parentControl) as ParentControlDesigner;
                    if (parentControlDesigner != null) { 
                        // Determine bounds of all controls
                        //
                        Rectangle bounds = Rectangle.Empty;
 
                        foreach (IComponent component in componentsArray) {
                            Control childControl = component as Control; 
 
                            if (childControl != null && childControl != parentControl && childControl.Parent == null) {
                                if (bounds.IsEmpty) { 
                                    bounds = childControl.Bounds;
                                }
                                else {
                                    bounds = Rectangle.Union(bounds, childControl.Bounds); 
                                }
                            } 
                        } 

                        defaultValues.Remove("Size");    // don't care about the drag size 
                        foreach (IComponent component in componentsArray) {
                            Control childControl = component as Control;
                            Form form = childControl as Form;
                            if (childControl != null 
                                && !(form != null && form.TopLevel) // Don't add top-level forms
                                && childControl.Parent == null) { 
                                    defaultValues["Offset"] = new Size(childControl.Bounds.X - bounds.X, childControl.Bounds.Y - bounds.Y); 
                                    parentControlDesigner.AddControl(childControl, defaultValues);
                            } 
                        }
                    }
                }
 

                // VSWhidbey 516338 - When creating an item for the tray, template items will have 
                // an old location stored in them, so they may show up on top of other items. 
                // So we need to call UpdatePastePositions for each one to get the tray to
                // arrange them properly. 
                //
                ComponentTray tray = (ComponentTray)host.GetService(typeof(ComponentTray));

                if (tray != null) { 
                    foreach(IComponent component in componentsArray) {
                        ComponentTray.TrayControl c = tray.GetTrayControlFromComponent(component); 
 
                        if (c != null) {
                            if (trayComponents == null) { 
                                trayComponents = new ArrayList();
                            }
                            trayComponents.Add(c);
                        } 
                    }
 
                    if (trayComponents != null) { 
                        tray.UpdatePastePositions(trayComponents);
                    } 
                }

                return componentsArray;
            } 

            protected override IComponent[] CreateComponentsCore(IDesignerHost host) { 
                return CreateComponentsCore(host, null); 
            }
        } 
    }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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