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

简介: 前言 在可扩展性开发(五)中,我介绍了对于Solution、Project、ProjectItem的基本操作。可以认为它们面向的是解决方案内容的物理(文件)表示,我们需要使用VS提供的解决方案管理器(Solution Explorer)来管理它们。

前言

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

工具窗口内的层次结构

如果你观察一下解决方案管理器和服务器管理器(Server Explorer),就会发现它们都使用树形结构来表现背后的数据。在AOM中,UIHierarchyUIHierarchyItemsUIHierarchyItem用于表示这样的层次结构。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示例

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

collapse-all-projects-menu

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

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"false0, slnCommandBar.Controls.Count + 1);
}

QueryStatus()
{
    
    
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

目录
相关文章
Visual Studio Code开发常用的工具栏选项,查看源码技巧以及【vscode常用的快捷键】
Visual Studio Code开发常用的工具栏选项,查看源码技巧以及【vscode常用的快捷键】
555 0
|
2月前
|
NoSQL 编译器 C语言
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查、性能分析和符号调试。通过实践案例学习如何有效定位和解决问题,同时注意保持耐心、合理利用工具、记录过程并避免过度调试,以提高编程能力和开发效率。
53 1
|
3月前
|
前端开发 JavaScript C#
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
CodeMaid:一款基于.NET开发的Visual Studio代码简化和整理实用插件
|
4月前
|
存储 运维
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
|
6月前
|
C++ Windows
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
在Windows上使用Visual Studio 2022进行FFmpeg和SDL2集成开发,首先安装FFmpeg至E:\msys64\usr\local\ffmpeg,然后新建C++控制台项目。在项目属性中,添加FFmpeg和SDL2的头文件及库文件目录。接着配置链接器的附加依赖项,包括多个FFmpeg及SDL2的lib文件。在代码中引入FFmpeg的`av_log`函数输出"Hello World",编译并运行,若看到"Hello World",即表示集成成功。详细步骤可参考《FFmpeg开发实战:从零基础到短视频上线》。
259 0
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
|
6月前
|
人工智能 前端开发 Devops
NET技术在现代开发中的影响力日益增强,本文聚焦其核心价值,如多语言支持、强大的Visual Studio工具、丰富的类库和跨平台能力。
【7月更文挑战第4天】**.NET技术在现代开发中的影响力日益增强,本文聚焦其核心价值,如多语言支持、强大的Visual Studio工具、丰富的类库和跨平台能力。实际应用涵盖企业系统、Web、移动和游戏开发,以及云服务。面对性能挑战、容器化、AI集成及跨平台竞争,.NET持续创新,开发者应关注技术趋势,提升技能,并参与社区,共同推进技术发展。**
52 1
使用 Visual Studio 开发 CS 的 BOF
使用 Visual Studio 开发 CS 的 BOF
|
前端开发 JavaScript PHP
Visual Studio Code的使用心得与常用免费插件使用技巧大全总结 老板夸奖我是开发小能手!
这就是我一直在使用的免费代码编辑神器, 它的优点太多了, 有: 智能感知、代码调试、内置 Git 命令、可扩展和可定制都相当牛,最关键的是免费开源!!
394 3
Visual Studio Code的使用心得与常用免费插件使用技巧大全总结 老板夸奖我是开发小能手!
|
Web App开发 JavaScript 前端开发
Visual Studio Code 常见的配置、常用好用插件以及【vsCode 开发相应项目推荐安装的插件】
Visual Studio Code 常见的配置、常用好用插件以及【vsCode 开发相应项目推荐安装的插件】
350 0
|
开发框架 .NET 数据库
asp.net企业费用报销管理信息系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
asp.net 企业费用报销管理信息系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使 用c#语言开发 应用技术:asp.net c#+sqlserver 开发工具:vs2010 +sqlserver
109 0