/// <summary> /// Returns a dataobject from selected nodes /// </summary> /// <param name="cutHighlightItems">boolean that defines if the selected items must be cut</param> /// <returns>data object for selected items</returns> internal virtual DataObject PackageSelectionDataObject(bool cutHighlightItems) { this.CleanupSelectionDataObject(false, false, false); StringBuilder sb = new StringBuilder(); DataObject dataObject = null; try { IList<HierarchyNode> selectedNodes = this.GetSelectedNodes(); if(selectedNodes != null) { this.InstantiateItemsDraggedOrCutOrCopiedList(); StringBuilder selectionContent = null; // If there is a selection package the data if(selectedNodes.Count > 1) { foreach(HierarchyNode node in selectedNodes) { selectionContent = node.PrepareSelectedNodesForClipBoard(); if(selectionContent != null) { sb.Append(selectionContent); } } } else if(selectedNodes.Count == 1) { HierarchyNode selectedNode = selectedNodes[0]; selectionContent = selectedNode.PrepareSelectedNodesForClipBoard(); if(selectionContent != null) { sb.Append(selectionContent); } } } // Add the project items first. IntPtr ptrToItems = this.PackageSelectionData(sb, false); if(ptrToItems == IntPtr.Zero) { return null; } FORMATETC fmt = DragDropHelper.CreateFormatEtc(DragDropHelper.CF_VSSTGPROJECTITEMS); dataObject = new DataObject(); dataObject.SetData(fmt, ptrToItems); // Now add the project path that sourced data. We just write the project file path. IntPtr ptrToProjectPath = this.PackageSelectionData(new StringBuilder(this.GetMkDocument()), true); if(ptrToProjectPath != IntPtr.Zero) { dataObject.SetData(DragDropHelper.CreateFormatEtc(DragDropHelper.CF_VSPROJECTCLIPDESCRIPTOR), ptrToProjectPath); } if (cutHighlightItems) { bool first = true; IVsUIHierarchyWindow w = UIHierarchyUtilities.GetUIHierarchyWindow(this.site, HierarchyNode.SolutionExplorer); // This happens in the context of cutting multiple items from the project. // Since we are already in solution explorer, it is extremely unlikely that we get a null return. // If we do, the icons for the cut items will not fade. The cut operation will still succeed. if (w != null) { foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied) { ErrorHandler.ThrowOnFailure(w.ExpandItem(this.InteropSafeIVsUIHierarchy, node.ID, first ? EXPANDFLAGS.EXPF_CutHighlightItem : EXPANDFLAGS.EXPF_AddCutHighlightItem)); first = false; } } } } catch(COMException e) { Trace.WriteLine("Exception : " + e.Message); dataObject = null; } return dataObject; }