Ejemplo n.º 1
0
        /// <summary>
        /// Renames the file in the hierarchy by removing old node and adding a new node in the hierarchy.
        /// </summary>
        /// <param name="oldFileName">The old file name.</param>
        /// <param name="newFileName">The new file name</param>
        /// <param name="newParentId">The new parent id of the item.</param>
        /// <returns>The newly added FileNode.</returns>
        /// <remarks>While a new node will be used to represent the item, the underlying MSBuild item will be the same and as a result file properties saved in the project file will not be lost.</remarks>
        protected virtual FileNode RenameFileNode(string oldFileName, string newFileName, uint newParentId)
        {
            if (string.Compare(oldFileName, newFileName, StringComparison.Ordinal) == 0)
            {
                // We do not want to rename the same file
                return(null);
            }

            this.OnItemDeleted();
            this.Parent.RemoveChild(this);

            // Since this node has been removed all of its state is zombied at this point
            // Do not call virtual methods after this point since the object is in a deleted state.

            string[] file = new string[1];
            file[0] = newFileName;
            VSADDRESULT[] result    = new VSADDRESULT[1];
            Guid          emptyGuid = Guid.Empty;

            ErrorHandler.ThrowOnFailure(this.ProjectMgr.AddItemWithSpecific(newParentId, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, 0, file, IntPtr.Zero, 0, ref emptyGuid, null, ref emptyGuid, result));
            FileNode childAdded = this.ProjectMgr.FindChild(newFileName) as FileNode;

            Debug.Assert(childAdded != null, "Could not find the renamed item in the hierarchy");
            // Update the itemid to the newly added.
            this.ID = childAdded.ID;

            // Remove the item created by the add item. We need to do this otherwise we will have two items.
            // Please be aware that we have not removed the ItemNode associated to the removed file node from the hierrachy.
            // What we want to achieve here is to reuse the existing build item.
            // We want to link to the newly created node to the existing item node and addd the new include.

            //temporarily keep properties from new itemnode since we are going to overwrite it
            string newInclude  = childAdded.ItemNode.Item.EvaluatedInclude;
            string dependentOf = childAdded.ItemNode.GetMetadata(ProjectFileConstants.DependentUpon);

            childAdded.ItemNode.RemoveFromProjectFile();

            // Assign existing msbuild item to the new childnode
            childAdded.ItemNode = this.ItemNode;
            childAdded.ItemNode.Item.ItemType    = this.ItemNode.ItemName;
            childAdded.ItemNode.Item.Xml.Include = newInclude;
            if (!string.IsNullOrEmpty(dependentOf))
            {
                childAdded.ItemNode.SetMetadata(ProjectFileConstants.DependentUpon, dependentOf);
            }
            childAdded.ItemNode.RefreshProperties();

            //Update the new document in the RDT.
            DocumentManager.RenameDocument(this.ProjectMgr.Site, oldFileName, newFileName, childAdded.ID);

            //Select the new node in the hierarchy
            IVsUIHierarchyWindow uiWindow = UIHierarchyUtilities.GetUIHierarchyWindow(this.ProjectMgr.Site, SolutionExplorer);

            ErrorHandler.ThrowOnFailure(uiWindow.ExpandItem(this.ProjectMgr, this.ID, EXPANDFLAGS.EXPF_SelectItem));

            //Update FirstChild
            childAdded.FirstChild = this.FirstChild;

            //Update ChildNodes
            SetNewParentOnChildNodes(childAdded);
            RenameChildNodes(childAdded);

            return(childAdded);
        }