Visual Studio 2008 可扩展性开发(六):操作Solution Explorer

前言

在可扩展性开发(五)中,我介绍了对于Solution、Project、ProjectItem的基本操作。可以认为它们面向的是解决方案内容的物理(文件)表示,我们需要使用VS提供的解决方案管理器(Solution Explorer)来管理它们。毫无疑问,解决方案管理器是VS中最重要的UI元素之一,本文将介绍对它的操作。

工具窗口内的层次结构

如果你观察一下解决方案管理器和服务器管理器(Server Explorer),就会发现它们都使用树形结构来表现背后的数据。在AOM中,UIHierarchy、UIHierarchyItems和UIHierarchyItem用于表示这样的层次结构。UIHierarchy表示根节点,它的UIHierarchyItems集合表示其所包含的第一级子节点(UIHierarchyItem),每一个UIHierarchyItem同时也有UIHierarchyItems属性,如此递归下去。这种结构很像它们所表示的数据:Solution、Project以及ProjectItem。在使用这些对象之前,先大致了解一下它们的主要成员:

1)UIHierarchy

Parent:节点对象的父节点;

SelectedItems:当前节点选中的子节点集合;

UIHierarchyItems:当前节点的子节点集合;

DoDefaultAction():对节点进行默认操作,类似于进行双击或按下回车键;

GetItem():按指定路径返回一个子节点;

SelectDown():选中当前选中节点的下个节点;

SelectUp():选中当前选中节点的上个节点;

更多信息请参看MSDN。

2)UIHierarchyItems集合

Expanded:获取或设置所表示的节点是否已展开;

Parent:节点集合的父节点;

Item():返回集合中的一项;

更多信息请参看MSDN。

3)UIHierarchyItem

IsSelected:获取节点是否被选中;

Name:节点对象的名称;

Select():选中节点;

更多信息请参看MSDN。

有了这些知识,我们现在有能力去探索对解决方案管理器的操作了。

CollapseAllProjects示例

项目刚开始的时候,项目的数量也许还不太多,随着程序规模的增大,项目数量也会不断增加,这时要找到某个项目或者某个文件,就变得越来越麻烦,你得先把大量的项目折叠起来。如果有一个命令,可以快速地折叠起所有项目,就方便多了:

这里的思路很简单,只要找到所有的项目节点,依次查看每个项目,如果项目展开了,就把它折叠起来。

0)添加命令

之前我们曾添加过CloseAllDocuments和NPetshopSlnGenerator命令(见可扩展性开发四、五),它们分别加在文本编辑器的标签和Tools菜单上,这里的过程没什么不同:

C# Code - 添加CollapseAllProjects命令

OnConnection()

{

    

    // Get "Solution Explorer" command bar

    CommandBar slnCommandBar = GetCommandBarByName("Solution");

    // Add a new command

    AddNamedCommand2(slnCommandBar, COLLAPSE_ALL_PROJECTS_COMMAND_NAME,

        "Collapse All Projects", "Collapse All Projects", false, 0, slnCommandBar.Controls.Count + 1);

}

Query
Status()

{

    

    else if (commandName == GetCommandFullName(COLLAPSE_ALL_PROJECTS_COMMAND_NAME))

    {

        status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;

        return;

    }

}

Exec()

{

    

    else if (commandName == GetCommandFullName(COLLAPSE_ALL_PROJECTS_COMMAND_NAME))

    {

        CollapseAllProjects();

handled = true;

        return;

    }

}

这里通过“Solution”找到解决方案节点的上下文菜单。

1)找到所有项目节点

C# Code -
查找所有的项目节点

/// 

/// 解决方案管理器根节点

/// 

protected UIHierarchy SolutionExplorerNode

{

    get

    {

        return _applicationObject.ToolWindows.SolutionExplorer;

    }

}

/// 

/// 获取指定解决方案内的项目节点

/// 

public List<UIHierarchyItem> GetProjectNodes(Solution solution)

{

    string solutionName = solution.Properties.Item("Name").Value.ToString();

    return GetProjectNodes(SolutionExplorerNode.GetItem(solutionName).UIHierarchyItems);

}

/// 

/// 循环解决方案的顶级节点以获取所有的项目节点

/// 

public List<UIHierarchyItem> GetProjectNodes(UIHierarchyItems topLevelItems)

{

    List<UIHierarchyItem> projects = new List<UIHierarchyItem>();

    foreach (UIHierarchyItem item in topLevelItems)

    {

        if (IsProjectNode(item))

        {

            projects.Add(item);

        }

        else if (IsSolutionFolder(item))

        {

            projects.AddRange(GetProjectNodesInSolutionFolder(item));

        }

    }

return projects;

}

/// 

/// 获取解决方案文件夹内的项目节点

/// 

private List<UIHierarchyItem> GetProjectNodesInSolutionFolder(UIHierarchyItem item)

{

    List<UIHierarchyItem> projects = new List<UIHierarchyItem>();

if (IsSolutionFolder(item))

    {

        foreach (UIHierarchyItem subItem in item.UIHierarchyItems)

        {

            if (IsProjectNode(subItem))

            {

                projects.Add(subItem);

            }

        }

    }

return projects;

}

/// 

/// 判断节点是否为解决方案文件夹

/// 

private bool IsSolutionFolder(UIHierarchyItem item)

{

    return ((item.Object is Project) &&

        ((item.Object as Project).Kind == ProjectKinds.vsProjectKindSolutionFolder));

}

/// 

/// 判断节点是否为项目(可能是顶级节点,也可能在解决方案文件夹中)

/// 

private bool IsProjectNode(UIHierarchyItem item)

{

    return IsDirectProjectNode(item) || IsProjectNodeInSolutionFolder(item);

}

/// 

/// 判断节点是否为顶级的项目

/// 

private bool IsDirectProjectNode(UIHierarchyItem item)

{

    return ((item.Object is Project) && ((item.Object as Project).Kind != ProjectKinds.vsProjectKindSolutionFolder));

}

/// 

/// 判断节点是否为包含在解决方案文件夹中的项目

/// 

private bool IsProjectNodeInSolutionFolder(UIHierarchyItem item)

{

    return (item.Object is ProjectItem && ((ProjectItem)item.Object).Object is Project &&

                ((Project)((ProjectItem)item.Object).Object).Kind != ProjectKinds.vsProjectKindSolutionFolder);

}

也许比预想的要复杂些,主要的原因是解决方案文件夹的存在,解决方案文件夹本身也被看作Project对象,同时它又可以包含其它真正的项目,所以在查找项目的时候要分两种情况。先查找解决方案下面的项目,然后再查找解决方案文件夹下面的项目。

2)折叠所有项目节点

C# Code - 折叠所有项目节点

private void CollapseAllProjects()

{

    Solution sln = _applicationObject.Solution;

    List<UIHierarchyItem> projects = GetProjectNodes(sln);

    foreach (UIHierarchyItem item in projects)

    {

        CollapseProject(item);

    }

}

private void CollapseProject(UIHierarchyItem project)

{

    if (project.UIHierarchyItems.Expanded)

    {

        if (IsDirectProjectNode(project))

        {

            project.UIHierarchyItems.Expanded = false;

        }

        else if (IsProjectNodeInSolutionFolder(project))

        {

            project.Select(vsUISelectionType.vsUISelectionTypeSelect);

            SolutionExplorerNode.DoDefaultAction();

        }

    }

}

这里就简单了,对于每个项目,通过Expanded属性判断它是否已展开,如果是的话将其折叠起来,此时也要分两种情况进行考虑。

以后就不用再为那些包含数十个项目的解决方案发愁了:)

可以从这里下载代码,也可以在这里下载可运行的Add-In(解压缩后将文件放在[My Documents Path]\Visual Studio 2008\Addins下)。

我们身在何处?

在解决方案、项目和项之后,本文介绍了对解决方案管理器的操作,现在我们有办法来解决这些方面的问题了。接下来,我将介绍Add-In开发的重头戏——文本编辑器的操作。

参考

《Professional Visual Studio® 2008 Extensibility》
《Working with Microsoft Visual Studio® 2005》
PowerCommands Project

时间: 2024-10-24 00:29:32

Visual Studio 2008 可扩展性开发(六):操作Solution Explorer的相关文章

Visual Studio 2008可扩展性开发(九):总结篇

可以说木匠让小时的我第一次感受到了专业,虽然那时还不知道专业这个词,尤其是 那些有年纪的老木匠,专注地在那锯木头.钉钉子.刨出带着香味的木花.他们有其他人 所没有的工具,更重要的是他们掌握了那些工具.VS正是我们手头的工具,它可以是锤子 ,也可以是锯.刨子,如果你能掌握它,而且要掌握的好. 我向来喜欢了解手头工具的方方面面(也许与我的思维方式有关,总想了解得更多) .我甚至觉得,对于最常用的工具,了解得越多越好--今天掌握了一个小功能,未来两 三年都会受益. 上面是我对工具的一点感想.VS越来越

艾伟:Visual Studio 2008 可扩展性开发(六):操作Solution Explorer

前言 在可扩展性开发(五)中,我介绍了对于Solution.Project.ProjectItem的基本操作.可以认为它们面向的是解决方案内容的物理(文件)表示,我们需要使用VS提供的解决方案管理器(Solution Explorer)来管理它们.毫无疑问,解决方案管理器是VS中最重要的UI元素之一,本文将介绍对它的操作. 工具窗口内的层次结构 如果你观察一下解决方案管理器和服务器管理器(Server Explorer),就会发现它们都使用树形结构来表现背后的数据.在AOM中,UIHierarc

Visual Studio 2008 可扩展性开发(一):VS概览

前言 Visual Studio是微软最知名的产品之一,在使用微软技术的开发人员的心目中尤为如此.相信这一点无须多说.它建立在IDE(统一开发环境)的基础之上,可用于开发多种不同类型的应用程序. Visual Studio,通常被简称为VS(以下皆按此简称),支持多种平台和编程语言.了解VS的历史以及每个版本的更迭,对学习它的扩展性开发会很有好处.所以在这里简单地说说VS在过去的12年里的历史. VS的历史 在软件领域,VS的历史算比较长的了.在此期间,微软开发了数种编程语言和支持这些语言的可视

Visual Studio 2008 可扩展性开发(二):Macro和Add-In初探

  前言 在VS概览中,我们简单回顾了一下VS的历史.本文将通过两个简单的例子来说明Macro和Add-In的开发.通过Macro我们把VS中的一些重复操作录制下来,之后可以多次运行,节省时间并保持好的心情:通过Add-In,我们可以自己动手来为VS添加新的功能,扩展了VS就意味着扩展了我们自己. VS 2008扩展方式一览  在上篇VS概览中提到了扩展VS有三种主要的方式:Macro.Add-In和VsPackage.事实上,还有更多的选择,这里先简单列一下: Macro Add-In VsP

Visual Studio 2008 可扩展性开发(三):Add-In运行机制解析(下)

前言 在上篇Add-In运行机制解析(上)中,我分析了Add-In向导生成的代码,从中我们知道只要创建一个类库,它包含实现了IDTExtensibility2接口的类,然后为其建立.addin配置文件,就可以实现一个Add-In了.本文将更进一步,介绍Add-In的事件和生命周期,为今后的开发打下基础. Add-In的事件 Add-In是事件驱动的,可以猜到的事件有加载.卸载.状态改变等等.事实上,这些事件都与IDTExtensibility2接口有关,也就是该接口的5个方法: 如果要了解这些方

Visual Studio 2008 可扩展性开发(三):Add-In运行机制解析(上)

前言 上一篇随笔Macro和Add-In初探介绍了如何开发两者的HelloWorld程序.没错,宏确实简单易行.不过在某些情况下,比如在商业软件中,宏在性能和知识产权方面可能会带来麻烦,此时那把更好的锤子是Add-In. 在初探一文中,我介绍了如何使用Add-In向导来开发第一个Add-In.VS是一款很棒的开发工具,它的各种向导(以及其它模板.可视化工具等)做得非常好,不过我发现这一强大之处到头来反而给人诟病.其中一种说法是,这些方便的工具让初学者入门容易,并惯坏了他们,以致于想登堂入室就难得

Visual Studio 2008可扩展性开发(六):操作Solution Explorer

前言 在可扩展性开发(五)中,我介绍了对于Solution.Project.ProjectItem的基本操 作.可以认为它们面向的是解决方案内容的物理(文件)表示,我们需要使用VS提供的解 决方案管理器(Solution Explorer)来管理它们.毫无疑问,解决方案管理器是VS中最 重要的UI元素之一,本文将介绍对它的操作. 工具窗口内的层次结构 如果你观察一下解决方案管理器和服务器管理器(Server Explorer),就会发现它们 都使用树形结构来表现背后的数据.在AOM中,UIHie

Visual Studio 2008可扩展性开发(七):操作文本编辑器

前言 在可扩展性开发(六)中,我介绍了对于Solution Explorer的基本操作.不过,对咱 们开发人员来说,绝大部分时间面对的还是编辑器. VS2008的编辑器功能已经颇为强大了,如果我们能熟练使用快捷键,编写代码的过程 是相当舒服的,就像<卓有成效的程序员>中所说: "编程时始终优先使用键盘而非鼠标" 但问题在于,VS面向的是所有的开发人员群体,它只能够提供最通用的功能,如果对 VS的编辑器有些额外的需求,我们只好自己动手了,本文将介绍如何扩展文本编辑器. AOM

Visual Studio 2008可扩展性开发(一):VS概览

前言 Visual Studio是微软最知名的产品之一,在使用微软技术的开发人员的心目中尤为如 此.相信这一点无须多说.它建立在IDE(统一开发环境)的基础之上,可用于开发多种 不同类型的应用程序. Visual Studio,通常被简称为VS(以下皆按此简称),支持多种平台和编程语言.了 解VS的历史以及每个版本的更迭,对学习它的扩展性开发会很有好处.所以在这里简单地 说说VS在过去的12年里的历史. VS的历史 在软件领域,VS的历史算比较长的了.在此期间,微软开发了数种编程语言和支持这 些