<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David DeWinter &#187; VSX</title>
	<atom:link href="http://davedewinter.com/category/vsx/feed/" rel="self" type="application/rss+xml" />
	<link>http://davedewinter.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Tue, 09 Aug 2011 21:05:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>DBML Fixup Preview</title>
		<link>http://davedewinter.com/2008/08/24/dbml-fixup-preview/</link>
		<comments>http://davedewinter.com/2008/08/24/dbml-fixup-preview/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 03:41:44 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[DBML Fixup]]></category>
		<category><![CDATA[LINQ to SQL]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>
		<category><![CDATA[VSX]]></category>
		<category><![CDATA[DBML]]></category>
		<category><![CDATA[DBML Sync]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[LINQ to SQL Designer]]></category>
		<category><![CDATA[Schema Sync]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/2008/08/24/dbml-fixup-preview/</guid>
		<description><![CDATA[Back in February I blogged about DBML Fixup&#8212;a tool whose goal was to sync LINQ to SQL models with their respective database schemas from within the Visual Studio environment, as well as to handle running various fixup tasks on models. &#8230; <a href="http://davedewinter.com/2008/08/24/dbml-fixup-preview/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Back in <a href="http://blogs.rev-net.com/ddewinter/2008/02/16/linq-to-sql-and-database-schema-sync/">February</a> I blogged about DBML Fixup&#8212;a tool whose goal was to sync LINQ to SQL models with their respective database schemas from within the Visual Studio environment, as well as to handle running various fixup tasks on models. Now it&#8217;s six months later, and I have a much clearer vision of what the tool is meant to be as well as a firmer command on VSX. The following screencast is a preview of the features of DBML Fixup.</p>
<p>&#160;</p>
<div id="media"><object id="csSWF" codebase="http://active.macromedia.com/flash7/cabs/ swflash.cab#version=9,0,28,0" height="498" width="640" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"><param name="_cx" value="16933"><param name="_cy" value="13176"><param name="FlashVars" value=""><param name="Movie" value="http://blogs.rev-net.com/ddewinter/wp-content/screencasts/dbmlfixup/DBMLFixupAug08.swf"><param name="Src" value="http://blogs.rev-net.com/ddewinter/wp-content/screencasts/dbmlfixup/DBMLFixupAug08.swf"><param name="WMode" value="Window"><param name="Play" value="0"><param name="Loop" value="-1"><param name="Quality" value="High"><param name="SAlign" value=""><param name="Menu" value="-1"><param name="Base" value=""><param name="AllowScriptAccess" value="always"><param name="Scale" value="ShowAll"><param name="DeviceFont" value="0"><param name="EmbedMovie" value="0"><param name="BGColor" value="1A1A1A"><param name="SWRemote" value=""><param name="MovieData" value=""><param name="SeamlessTabbing" value="1"><param name="Profile" value="0"><param name="ProfileAddress" value=""><param name="ProfilePort" value="0"><param name="AllowNetworking" value="all"><param name="AllowFullScreen" value="true"><embed name="csSWF" src="http://blogs.rev-net.com/ddewinter/wp-content/screencasts/dbmlfixup/DBMLFixupAug08.swf" width="640" height="498" bgcolor="#1a1a1a" quality="best" allowscriptaccess="always" allowfullscreen="true" scale="showall" flashvars="autostart=false" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></embed></object></div>
<p>&#160;</p>
<p>Here are some previous posts which (briefly) describe the domain:</p>
<p><a title="http://blogs.rev-net.com/ddewinter/2008/02/16/the-linq-to-sql-model/" href="http://blogs.rev-net.com/ddewinter/2008/02/16/the-linq-to-sql-model/">http://blogs.rev-net.com/ddewinter/2008/02/16/the-linq-to-sql-model/</a></p>
<p><a title="http://blogs.rev-net.com/ddewinter/2008/02/16/linq-to-sql-and-database-schema-sync/" href="http://blogs.rev-net.com/ddewinter/2008/02/16/linq-to-sql-and-database-schema-sync/">http://blogs.rev-net.com/ddewinter/2008/02/16/linq-to-sql-and-database-schema-sync/</a></p>
<p>&#160;</p>
<p>Any ideas about directions for the tool? Or maybe something that wasn&#8217;t covered in the screencast? I&#8217;d love to hear your ideas.</p>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/08/24/dbml-fixup-preview/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Dynamic Menu Commands in Visual Studio Packages &#8211; Part 3</title>
		<link>http://davedewinter.com/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/</link>
		<comments>http://davedewinter.com/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/#comments</comments>
		<pubDate>Sun, 06 Apr 2008 01:33:20 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[Visual Studio 2008]]></category>
		<category><![CDATA[VSX]]></category>
		<category><![CDATA[Context]]></category>
		<category><![CDATA[Custom]]></category>
		<category><![CDATA[Dynamic]]></category>
		<category><![CDATA[IVsMonitorSelection]]></category>
		<category><![CDATA[IVsSelectionEvents]]></category>
		<category><![CDATA[Menu]]></category>
		<category><![CDATA[SVsShellMonitorSelection]]></category>
		<category><![CDATA[UI Context]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/index.php/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/</guid>
		<description><![CDATA[This is the final post in a series detailing how to build dynamic menu commands in Visual Studio packages. The previous posts are located here: Part 1 &#8211; Discusses UI Contexts and how to utilize the built-in ones for dynamic &#8230; <a href="http://davedewinter.com/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the final post in a series detailing how to build dynamic menu commands in Visual Studio packages. The previous posts are located here:</p>
<ul>
<li><a href="http://blogs.rev-net.com/ddewinter/index.php/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/">Part 1</a> &#8211; Discusses UI Contexts and how to utilize the built-in ones for dynamic menu commands.</li>
<li><a href="http://blogs.rev-net.com/ddewinter/index.php/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/">Part 2</a> &#8211; Discusses the use of the BeforyQueryStatus event to provide more flexibility than built-in UI contexts.</li>
</ul>
<p>What we&#8217;ve explored to date is a way to provide dynamic menu commands (e.g. dynamic visibility, enabled state) in <em>our own</em> package, and the techniques that I&#8217;ve shown thus far have worked well for this scenario. However, if you want to develop multiple menu commands or even multiple packages that rely on a custom condition (as shown in Part 2), then you&#8217;re stuck implementing the same logic in an event handler for the <a href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.olemenucommand.beforequerystatus(VS.80).aspx">BeforeQueryStatus</a> event for each <a href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.olemenucommand(VS.80).aspx">OleMenuCommand</a>.</p>
<p>Wouldn&#8217;t it be great if we could create our own UI Context, similar to the built-in ones like UIContext_NoSolution or UIContext_FullScreenMode? That way we can create multiple menu commands that rely on that context or even multiple packages which rely on it.</p>
<p>And that&#8217;s exactly what this post will cover. We&#8217;ll use the <a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/dynamicmenudevelopment-part-2.zip">solution starting from where we left off at the end of Part 2</a>.</p>
<p><span id="more-90"></span></p>
<h3 style="margin-bottom: 10px">Step 1: Creating New Commands</h3>
<p>Because <a href="http://blogs.rev-net.com/ddewinter/index.php/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/">Part 2</a> covered how to create a new menu command from scratch using the VSCT file and the appropriate procedural code, I&#8217;m not going to cover the process in depth here. I&#8217;ll be creating two new menu commands, which will be part of the command set that we created in Part 2 (guidDynamicMenuDevelopmentCmdSetPart2 in the GuidList class). In the snippets that follow, the bold sections indicate what I added to achieve this:</p>
<h4 style="margin-bottom: 10px">PkgCmdIDList Class (in PkgCmdID.cs)</h4>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue;">static</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">PkgCmdIDList</span></p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">uint</span> cmdidBuiltInUIContext =        0&#215;100;</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">uint</span> cmdidQueryStatus      =        0&#215;101;</p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">uint</span> cmdidCustomUIContext  =        0&#215;102;</strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">uint</span> cmdidCustomUIContext2 =        0&#215;103;</strong></p>
<p style="margin: 0px; text-align: left">};</p>
</div>
<h4 style="margin-bottom: 10px">DynamicMenuDevelopment.vsct File &#8211; Symbols Element</h4>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue;">&lt;</span><span style="color: #a31515;">GuidSymbol</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSetPart2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">{9d9046da-94f8-4fd0-8a00-92bf4f6defa8}</span>&#8220;<span style="color: blue;">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;"> &lt;</span><span style="color: #a31515;">IDSymbol</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">menuidQueryStatusGroup</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">0&#215;1020</span>&#8220;<span style="color: blue;">/&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;"> &lt;</span><span style="color: #a31515;">IDSymbol</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidQueryStatus</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">0&#215;0101</span>&#8220;<span style="color: blue;"> /&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;"> <strong>&lt;</strong></span><strong><span style="color: #a31515;">IDSymbol</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidCustomUIContext</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">0&#215;0102</span>&#8220;<span style="color: blue;"> /&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;"> <strong>&lt;</strong></span><strong><span style="color: #a31515;">IDSymbol</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidCustomUIContext2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">0&#215;0103</span>&#8220;<span style="color: blue;"> /&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">&lt;/</span><span style="color: #a31515;">GuidSymbol</span><span style="color: blue;">&gt;</span></p>
</div>
<h4 style="margin-bottom: 10px">DynamicMenuDevelopment.vsct File &#8211; Buttons Element</h4>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">&lt;</span><span style="color: #a31515;">Button</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSetPart2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidCustomUIContext</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">priority</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">0&#215;1</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">type</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">Button</span>&#8220;<span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">Parent</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSetPart2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">menuidQueryStatusGroup</span>&#8220;<span style="color: blue;">/&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">Icon</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidImages</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">bmpPicSearch</span>&#8220;<span style="color: blue;">/&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">CommandFlag</span><span style="color: blue;">&gt;</span>DynamicVisibility<span style="color: blue;">&lt;/</span><span style="color: #a31515;">CommandFlag</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">Strings</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">CommandName</span><span style="color: blue;">&gt;</span>cmdidCustomUIContext<span style="color: blue;">&lt;/</span><span style="color: #a31515;">CommandName</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><br />
<span style="color: blue;"> &lt;</span><span style="color: #a31515;">ButtonText</span><span style="color: blue;">&gt;</span>Custom UI Context 1<span style="color: blue;">&lt;/</span><span style="color: #a31515;">ButtonText</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;/</span><span style="color: #a31515;">Strings</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">&lt;/</span><span style="color: #a31515;">Button</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">&lt;</span><span style="color: #a31515;">Button</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSetPart2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidCustomUIContext2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">priority</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">0&#215;2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">type</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">Button</span>&#8220;<span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">Parent</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSetPart2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">menuidQueryStatusGroup</span>&#8220;<span style="color: blue;">/&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">Icon</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidImages</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">bmpPicX</span>&#8220;<span style="color: blue;">/&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">CommandFlag</span><span style="color: blue;">&gt;</span>DynamicVisibility<span style="color: blue;">&lt;/</span><span style="color: #a31515;">CommandFlag</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">Strings</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">CommandName</span><span style="color: blue;">&gt;</span>cmdidCustomUIContext2<span style="color: blue;">&lt;/</span><span style="color: #a31515;">CommandName</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">ButtonText</span><span style="color: blue;">&gt;</span>Custom UI Context 2<span style="color: blue;">&lt;/</span><span style="color: #a31515;">ButtonText</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;/</span><span style="color: #a31515;">Strings</span><span style="color: blue;">&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">&lt;/</span><span style="color: #a31515;">Button</span><span style="color: blue;">&gt;</span></strong></p>
</div>
<p>In summary, I added two IDs to the PkgCmdIDList class which specify the IDs of the two new menu commands I&#8217;m going to add. Furthermore, I registered these IDs in the VSCT file using IDSymbol elements in the guidDynamicMenuDevelopmentCmdSetPart2 GuidSymbol (which I mentioned earlier). Finally, I added two buttons to the Buttons element that map directly to the commands we created. At this point, we could create handlers for these commands, but it&#8217;s really not necessary for us to achieve what we want. If you press F5 and open a project that has at least one project item in it, you&#8217;ll see our two new menu commands when right clicking on a project item:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/04/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/04/image-thumb.png" border="0" alt="image" width="260" height="189" /></a></p>
<p>(These menu commands appear in the Solution Explorer because we defined their parents as being in the Solution Explorer context menu—see Post 2 for details.)</p>
<h3 style="margin-bottom: 10px">Step 2: Implementing the Custom UI Context</h3>
<p>For our custom UI context, let&#8217;s re-implement the functionality that the second command we created (in Post 2) did—display itself when a .dbml file is selected in the Solution Explorer but hide itself when anything else is selected. To do this we&#8217;ll need a way to tell Visual Studio what the current UI Context is. Fortunately, the <a style="color: #2b91af; font-family: courier new" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.svsshellmonitorselection(VS.80).aspx">SVsShellMonitorSelection</a> service, through the <a style="color: #2b91af; font-family: courier new" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivsmonitorselection(VS.80).aspx">IVsMonitorSelection</a> interface, exposes the functionality to get and set the current UI context (as well as means to track the current selection). This will definitely fit our needs, but how do we receive notifications when the current selection changes?</p>
<p>This is where the <a style="color: #2b91af; font-family: courier new" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivsselectionevents(VS.80).aspx">IVsSelectionEvents</a> interface really comes in handy. It doesn&#8217;t correspond to a specific Visual Studio service; instead, it&#8217;s used in tandem with the <a style="color: #2b91af; font-family: courier new" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivsmonitorselection(VS.80).aspx">IVsMonitorSelection</a> interface to receive notifications when the UI context has changed, when the current selection has changed, and when an element value has changed. The last notification is outside of the scope of this article, but <a href="http://www.sturmnet.org/blog/archives/2005/09/03/vs-window-tracking/">this blog post</a> may help you understand its purpose.</p>
<p>Is what we must do becoming clearer to you? If not, maybe the following steps will help:</p>
<ol>
<li>Create a UI context GUID that we can use for DBML file selection.</li>
<li>Implement the <a style="color: #2b91af; font-family: courier new" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivsselectionevents(VS.80).aspx">IVsSelectionEvents</a> interface.</li>
<li>Use that implementation with the <a style="color: #2b91af; font-family: courier new" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.svsshellmonitorselection(VS.80).aspx">SVsShellMonitorSelection</a> service to listen for selection events.</li>
<li>When the selection changes to a DBML file, set the UI context that we created in Step 1 as the active UI context.</li>
<li>Of course, the final step is to hook up our<br />
menu commands to this UI context to test our work.</li>
</ol>
<h4 style="margin-bottom: 10px">Creating the UI Context GUID</h4>
<p>This is probably the easiest step out of the five, as all it does is involve our creating a new GUID to put in the GuidList class that we can reference later. I&#8217;ll do this using guidgen.exe, accessible through the Tools &gt; Create GUID option in Visual Studio. The result looks like this:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue;">static</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">GuidList</span></p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">string</span> guidDynamicMenuDevelopmentPkgString = <span style="color: #a31515;">&#8220;d626ae3e-6eaa-414f-9a74-4f41fb902a23&#8243;</span>;</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">string</span> guidDynamicMenuDevelopmentCmdSetString = <span style="color: #a31515;">&#8220;a9d25ef1-3235-4a08-8c93-f26619635e91&#8243;</span>;</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">string</span> guidDynamicMenuDevelopmentCmdSetPart2String = <span style="color: #a31515;">&#8220;9d9046da-94f8-4fd0-8a00-92bf4f6defa8&#8243;</span>;</p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">public</span> <span style="color: blue;">const</span> <span style="color: blue;">string</span> UICONTEXT_DbmlFileSelectedString = <span style="color: #a31515;">&#8220;203116D4-FC70-48d8-A4E8-2467F58B1F65&#8243;</span>;</strong></p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Guid</span> guidDynamicMenuDevelopmentCmdSet = <span style="color: blue;">new</span> <span style="color: #2b91af;">Guid</span>(guidDynamicMenuDevelopmentCmdSetString);</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Guid</span> guidDynamicMenuDevelopmentCmdSetPart2 = <span style="color: blue;">new</span> <span style="color: #2b91af;">Guid</span>(guidDynamicMenuDevelopmentCmdSetPart2String);</p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">readonly</span> <span style="color: #2b91af;">Guid</span> UICONTEXT_DbmlFileSelected = <span style="color: blue;">new</span> <span style="color: #2b91af;">Guid</span>(UICONTEXT_DbmlFileSelectedString);</strong></p>
<p style="margin: 0px; text-align: left">};</p>
</div>
<h4 style="margin-bottom: 10px">Implementing the IVsSelectionEvents Interface</h4>
<p>This interface is fairly straightforward to implement. Before getting into the code, remember that we are checking what the new selection is when it changes. If it&#8217;s a DBML file in the Solution Explorer, then we activate our UI context. Here&#8217;s what my implementation looks like:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;summary&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: gray;">///</span><span style="color: green;"> Our implementation of the </span><span style="color: gray;">&lt;see cref=&#8221;IVsSelectionEvents&#8221;/&gt;</span><span style="color: green;"> interface,</span></p>
<p style="margin: 0px; text-align: left"><span style="color: gray;">///</span><span style="color: green;"> used to set a custom UI context GUID.</span></p>
<p style="margin: 0px; text-align: left"><span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;/summary&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">private</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SelectionEvents</span> : <span style="color: #2b91af;">IVsSelectionEvents</span></p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">IVsMonitorSelection</span> SelectionService;</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">uint</span> ContextCookie = RegisterContext();</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">uint</span> RegisterContext()</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: green;">// Initialize the selection service</span></p>
<p style="margin: 0px; text-align: left">SelectionService = (<span style="color: #2b91af;">IVsMonitorSelection</span>)<span style="color: #2b91af;">Package</span>.GetGlobalService(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">SVsShellMonitorSelection</span>));</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: green;">// Get a cookie for our UI Context. This &#8220;registers&#8221; our</span></p>
<p style="margin: 0px; text-align: left"><span style="color: green;">// UI context with the selection service so we can set it again later.</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">uint</span> retVal;</p>
<p style="margin: 0px; text-align: left"><span style="color: #2b91af;">Guid</span> uiContext = <span style="color: #2b91af;">GuidList</span>.UICONTEXT_DbmlFileSelected;</p>
<p style="margin: 0px; text-align: left">SelectionService.GetCmdUIContextCookie(<span style="color: blue;">ref</span> uiContext, <span style="color: blue;">out</span> retVal);</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: blue;">return</span> retVal;</p>
<p style="margin: 0px; text-align: left">}</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: green;">// We don&#8217;t care about either of these methods, but it&#8217;s useful to know what they do.</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">int</span> <span style="color: #2b91af;">IVsSelectionEvents</span>.OnCmdUIContextChanged(<span style="color: blue;">uint</span> dwCmdUICookie, <span style="color: blue;">int</span> fActive)</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">return</span> <span style="color: #2b91af;">VSConstants</span>.S_OK;</p>
<p style="margin: 0px">}</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">int</span> <span style="color: #2b91af;">IVsSelectionEvents</span>.OnElementValueChanged(<span style="color: blue;">uint</span> elementid, <span style="color: blue;">object</span> varValueOld, <span style="color: blue;">object</span> varValueNew)</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">return</span> <span style="color: #2b91af;">VSConstants</span>.S_OK;</p>
<p style="margin: 0px; text-align: left">}</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: blue;">int</span> <span style="color: #2b91af;">IVsSelectionEvents</span>.OnSelectionChanged(<span style="color: #2b91af;">IVsHierarchy</span> pHierOld, <span style="color: blue;">uint</span> itemidOld,</p>
<p style="margin: 0px; text-align: left"><span style="color: #2b91af;">IVsMultiItemSelect</span> pMISOld, <span style="color: #2b91af;">ISelectionContainer</span> pSCOld,</p>
<p style="margin: 0px; text-align: left"><span style="color: #2b91af;">IVsHierarchy</span> pHierNew, <span style="color: blue;">uint</span> itemidNew,</p>
<p style="margin: 0px; text-align: left"><span style="color: #2b91af;">IVsMultiItemSelect</span> pMISNew, <span style="color: #2b91af;">ISelectionContainer</span> pSCNew)</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">if</span> (pHierNew != <span style="color: blue;">null</span>)</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">object</span> fileName;</p>
<p style="margin: 0px; text-align: left">pHierNew.GetProperty(itemidNew, (<span style="color: blue;">int</span>)<span style="color: #2b91af;">__VSHPROPID</span>.VSHPROPID_Name, <span style="color: blue;">out</span> fileName);</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: blue;">if</span> (fileName != <span style="color: blue;">null</span> &amp;&amp; fileName.ToString().EndsWith(<span style="color: #a31515;">&#8220;.dbml&#8221;</span>))</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: green;">// If we meet the conditions, set the UI context to be active.</span></p>
<p style="margin: 0px; text-align: left">SelectionService.SetCmdUIContext(ContextCookie, 1);</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">return</span> <span style="color: #2b91af;">VSConstants</span>.S_OK;</p>
<p style="margin: 0px; text-align: left">}</p>
<p style="margin: 0px; text-align: left">}</p>
<p style="margin: 0px; text-align: left"><span style="color: green;">// Otherwise, deactivate it.</span></p>
<p style="margin: 0px; text-align: left">SelectionService.SetCmdUIContext(ContextCookie, 0);</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: blue;">return</span> <span style="color: #2b91af;">VSConstants</span>.S_OK;</p>
<p style="margin: 0px; text-align: left">}</p>
<p style="margin: 0px; text-align: left">}</p>
</div>
<p>The implementation should make sense based off my previous article. When the selection changes, we inspect the new <span style="font-family: courier new; color: #2b91af;">IVsHierarchy</span> to find its selection. If the name of the selection ends with &#8220;.dbml&#8221;, then we are dealing with a DBML file. We activate the UI context in this case, and deactivate it in all other cases. Before any of that happens, though, we have to register the UI context GUID with the <a style="color: #2b91af; font-family: courier new" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.svsshellmonitorselection(VS.80).aspx">SVsShellMonitorSelection</a> service, which is what the <span style="font-family: courier new;">RegisterContext()</span> method does. The cookie that we receive from the call to <span style="font-family: courier new;">IVsMonitorSelection.GetCmdUIContextCookie()</span> is then used to set the UI context later on. There&#8217;s a bit of a trickery involved here to understand what&#8217;s going on, but most of it should be self-evident.</p>
<h4 style="margin-bottom: 10px">Registering the Selection Event Listener</h4>
<p>Now that we have a listener for the selection events, we need to register it with the selection service. To do this, add this to the <span style="font-family: courier new;">Initialize()</span> method in our package:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left">mySelectionEvents = <span style="color: blue;">new</span> <span style="color: #2b91af;">SelectionEvents</span>();</p>
<p style="margin: 0px; text-align: left"><span style="color: #2b91af;">IVsMonitorSelection</span> selectionService = (<span style="color: #2b91af;">IVsMonitorSelection</span>)<span style="color: blue;">this</span>.GetService(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">SVsShellMonitorSelection</span>));</p>
<p style="margin: 0px; text-align: left">selectionService.AdviseSelectionEvents(mySelectionEvents, <span style="color: blue;">out</span> mySelectionEventsCookie);</p>
</div>
<p>Here, <span style="font-family: courier new;">mySelectionEvents</span> and <span style="font-family: courier new;">mySelectionEventsCookie</span> are private fields in the package class. The only unfamiliar territory is the <span style="font-family: courier new;">IVsMonitorSelection.AdviseSelectionEvents</span> method. Now, I am by no means a COM expert, but this pattern of <em>advising</em> for events and then <em>unadvising</em> for them later on seems to be a common task for applications that interact with COM. The fact that we can unadvise for the events implies that there is a unique identifier for an &#8220;advise.&#8221; This unique identifier is the cookie that is passed by reference into the call for advising for selection events. We store this value in a private field so we can unadvise at an appropriate time <em>i.e.</em> in the package&#8217;s <span style="font-family: courier new;">Dispose</span> method:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Dispose(<span style="color: blue;">bool</span> disposing)</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left"><span style="color: #2b91af;">IVsMonitorSelection</span> selectionService = (<span style="color: #2b91af;">IVsMonitorSelection</span>)<span style="color: blue;">this</span>.Ge<br />
tService(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">SVsShellMonitorSelection</span>));</p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">if</span> (selectionService != <span style="color: blue;">null</span>)</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left">selectionService.UnadviseSelectionEvents(mySelectionEventsCookie);</p>
<p style="margin: 0px; text-align: left">}</p>
<p style="margin: 0px; text-align: left">
<p style="margin: 0px; text-align: left"><span style="color: blue;">base</span>.Dispose(disposing);</p>
<p style="margin: 0px; text-align: left">}</p>
</div>
<h4 style="margin-bottom: 10px">Hooking Up the Menu Commands</h4>
<p>It&#8217;s been a long toll, but we&#8217;re almost to the end! The last step is to hook up our two menu commands to the UI context we created. <a href="http://blogs.rev-net.com/ddewinter/index.php/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/">Part 1</a> shows how to do this with built-in UI contexts, and doing it with a custom one is no different. The first step is to add the GUID for our custom UI context to the Symbols element. Then, we add VisibilityItem elements to the VisibilityConstraints section which hook up the menu commands to that context.</p>
<h5 style="margin-bottom: 10px">The GUID Symbol for the Custom UI Context</h5>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue;">&lt;</span><span style="color: #a31515;">GuidSymbol</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">UICONTEXT_DbmlFileSelected</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">{203116D4-FC70-48d8-A4E8-2467F58B1F65}</span>&#8220;<span style="color: blue;"> /&gt;</span></p>
</div>
<h5 style="margin-bottom: 10px">The Visibility Constraints</h5>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue;">&lt;</span><span style="color: #a31515;">VisibilityConstraints</span><span style="color: blue;">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;"> &lt;</span><span style="color: #a31515;">VisibilityItem</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSet</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidBuiltInUIContext</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">context</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">UICONTEXT_NoSolution</span>&#8220;<span style="color: blue;"> /&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;"> <strong>&lt;</strong></span><strong><span style="color: #a31515;">VisibilityItem</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSetPart2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidCustomUIContext</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">context</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">UICONTEXT_DbmlFileSelected</span>&#8220;<span style="color: blue;"> /&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><strong><span style="color: blue;"> &lt;</span><span style="color: #a31515;">VisibilityItem</span><span style="color: blue;"> </span><span style="color: red;">guid</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">guidDynamicMenuDevelopmentCmdSetPart2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">id</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">cmdidCustomUIContext2</span>&#8220;<span style="color: blue;"> </span><span style="color: red;">context</span><span style="color: blue;">=</span>&#8220;<span style="color: blue;">UICONTEXT_DbmlFileSelected</span>&#8220;<span style="color: blue;"> /&gt;</span></strong></p>
<p style="margin: 0px; text-align: left"><span style="color: blue;">&lt;/</span><span style="color: #a31515;">VisibilityConstraints</span><span style="color: blue;">&gt;</span></p>
</div>
<h3 style="margin-bottom: 10px">Step 3: The Results!</h3>
<p>Now that we&#8217;ve gone through that rigmarole, press F5 and load a project with a DBML file in it (or create a DBML file in some file). You&#8217;ll see that our two new menu commands (as well the menu command we implemented with the BeforeQueryStatus event handler in Part 2) show up only when right clicking on a DBML file.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/04/image1.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/04/image-thumb1.png" border="0" alt="image" width="260" height="189" /></a></p>
<p>This concludes both this article on building custom UI contexts and this series on dynamic menus in Visual Studio. I hope this and the past articles help in you Visual Studio Package development!</p>
<h3><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/04/dynamicmenudevelopment-part-3.zip">Associated Solution</a></h3>
<h4>Other Articles in the Series</h4>
<ul>
<li><a href="http://blogs.rev-net.com/ddewinter/index.php/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/">Part 1 &#8211; Using UI Contexts</a></li>
<li><a href="http://blogs.rev-net.com/ddewinter/index.php/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/">Part 2 &#8211; The BeforeQueryStatus Event</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>The VSCT PowerToy</title>
		<link>http://davedewinter.com/2008/03/28/the-vsct-powertoy/</link>
		<comments>http://davedewinter.com/2008/03/28/the-vsct-powertoy/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 23:52:52 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[VSX]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[VSCTPowerToy]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/index.php/2008/03/28/the-vsct-powertoy/</guid>
		<description><![CDATA[One thing that amazes me about the technical blogosphere is how fast information travels. Yesterday the VSX team blog posted an entry about the VSCT power toy, something that—from the screenshot shown in that entry—looks indispensable when working with packages. &#8230; <a href="http://davedewinter.com/2008/03/28/the-vsct-powertoy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One thing that amazes me about the technical blogosphere is how fast information travels. Yesterday the VSX team blog <a href="http://blogs.msdn.com/vsxteam/archive/2008/03/27/VSCT-PowerToy-.aspx">posted an entry about the VSCT power toy</a>, something that—from the screenshot shown in that entry—looks indispensable when working with packages. <a href="http://code.msdn.microsoft.com/VSCTPowerToy">The power toy</a>, which installs in Program Files by default under the VSCTPowerToy directory, is a stand-alone application whose UI breaks down the components of command tables from any VS package, or Visual Studio itself, into a logical tree-view of information, a part of which is shown below:
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image7.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="774" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb7.png" width="701" border="0"></a>
<p>The picture above illustrates the basic structure when the power toy analyzes Visual Studio itself. Because of how many commands there are in Visual Studio, it would be overwhelming to show them all in the image, so it may be more helpful to look at the command table for a specific package or VSCT file. If you&#8217;ve been reading this blog you can probably infer that my &#8220;favorite&#8221; package is the LINQ to SQL package, so let&#8217;s have at some more features of the tool with it. (For reference, from your Visual Studio 2008 install directory, it is in Common7IDEMicrosoft.VisualStudio.ORDesigner.DslPackage.dll.) Simply opening the DLL in the power toy gives us the following:
<p>&nbsp;<a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image8.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="620" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb8.png" width="832" border="0"></a> </p>
<p>As you can see, we can drill down into the menus exposed by the VSCT file embedded in the LINQ to SQL package assembly. Although small compared to the rest of Visual Studio, packages like these can really help you become familiar with the taxonomy of groups, menus, buttons, etc. that are involved in a command table. Another advantage is that it shows you the snippet of the file you have highlighted in the treeview. For example, since we highlighted the Association button in the picture above, a contextual snippet window below will show the following:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image9.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="252" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb9.png" width="832" border="0"></a> </p>
<p>And there it is, as specified in the original VSCT file. I am not sure about whether snippets from other files in their respective formats, or whether they show in a VSCT format like this one. Regardless, this functionality can be a great aid to package developers looking for an easy way to find their desired hooks within Visual Studio. Give this tool and try and be sure to check out the document (linked on <a href="http://code.msdn.microsoft.com/VSCTPowerToy/Release/ProjectReleases.aspx?ReleaseId=698">this page</a>) for more features!</p>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/03/28/the-vsct-powertoy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamic Menu Commands in Visual Studio Packages &#8211; Part 2</title>
		<link>http://davedewinter.com/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/</link>
		<comments>http://davedewinter.com/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 04:20:40 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[DBML Fixup]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>
		<category><![CDATA[VSX]]></category>
		<category><![CDATA[BeforeQueryStatus]]></category>
		<category><![CDATA[Commands]]></category>
		<category><![CDATA[Dynamic]]></category>
		<category><![CDATA[Extensibility]]></category>
		<category><![CDATA[Menu]]></category>
		<category><![CDATA[Orcas]]></category>
		<category><![CDATA[QueryStatus]]></category>
		<category><![CDATA[UI Context]]></category>
		<category><![CDATA[UIContext]]></category>
		<category><![CDATA[Visibility]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/?p=72</guid>
		<description><![CDATA[In this post I&#8217;ll be building on the principles of my last post with dynamic menu development in Visual Studio, so if you haven&#8217;t read that post please go back and check it out! If you remember from last time, &#8230; <a href="http://davedewinter.com/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this post I&#8217;ll be building on the principles of my <a href="http://blogs.rev-net.com/ddewinter/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/">last post</a> with dynamic menu development in Visual Studio, so if you haven&#8217;t read that post please go back and check it out!</p>
<p>If you remember from last time, we were able to create a dynamic menu command without any lines of procedural code (other than those generated by the wizard). The result was a menu command that showed itself only when no solution was loaded in Visual Studio. Immediately a solution was loaded, the menu command disappeared. The limitations of this approach are that you&#8217;re reliant on built-in UI contexts, such as UICONTEXT_NoSolution. However, what I needed for my <a href="http://blogs.rev-net.com/ddewinter/?p=41">DBML Fixup</a> project was a way to add menu commands when right clicking on .dbml files (LINQ to SQL Classes) in the Solution Explorer. The built-in UI contexts that we reviewed in the previous post are not enough to give us this functionality. In this tutorial, I take you through step-by-step on how to add this feature to your VS packages. We have to do a bit of digging though, so let&#8217;s get started!</p>
</p>
<p> <span id="more-88"></span>
</p>
<p> <strike></strike>
<p>The first thing we need to do is to create a new a menu command using our <a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/dynamicmenudevelopment-part-1.zip">existing solution</a>. Because we don&#8217;t have the wizard to help us this time, we&#8217;ll have to create our menu command from scratch.</p>
<h3 style="margin-bottom: 10px">Step 1: Creating the New Command</h3>
<p>Our first step is to create the GUID:ID pair that Visual Studio will use to identify our new menu command. The GUID represents a set of commands (or command set) exposed by this package; one of these was created by the package wizard when the solution was generated. However, for this part of the tutorial, we&#8217;ll go ahead and create a new command set in the Guids.cs file. (We can get a new GUID from the Tools &gt; Create GUID menu item.) Afterwards, my Guids.cs file looks like this:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">static</span> <span style="color: blue">class</span> <span style="color: #2b91af">GuidList</span></p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">const</span> <span style="color: blue">string</span> guidDynamicMenuDevelopmentPkgString = <span style="color: #a31515">&quot;d626ae3e-6eaa-414f-9a74-4f41fb902a23&quot;</span>;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">const</span> <span style="color: blue">string</span> guidDynamicMenuDevelopmentCmdSetString = <span style="color: #a31515">&quot;a9d25ef1-3235-4a08-8c93-f26619635e91&quot;</span>;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <strong><span style="color: blue">public</span> <span style="color: blue">const</span> <span style="color: blue">string</span> guidDynamicMenuDevelopmentCmdSetPart2String = <span style="color: #a31515">&quot;9d9046da-94f8-4fd0-8a00-92bf4f6defa8&quot;</span>;</strong></p>
<p style="margin: 0px; text-align: left">&#160;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">Guid</span> guidDynamicMenuDevelopmentCmdSet = <span style="color: blue">new</span> <span style="color: #2b91af">Guid</span>(guidDynamicMenuDevelopmentCmdSetString);</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <strong><span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">Guid</span> guidDynamicMenuDevelopmentCmdSetPart2 = <span style="color: blue">new</span> <span style="color: #2b91af">Guid</span>(guidDynamicMenuDevelopmentCmdSetPart2String);</strong></p>
<p style="margin: 0px; text-align: left">};</p>
</p></div>
<p>Pardon the unoriginal name of &quot;CmdSetPart2.&quot; The next step is to add an ID that maps to the specific menu command we are going to add. This can be changed in the PkgCmdID.cs file in our project. Here I will add the cmdidQueryStatusCommand with a value of 257:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">static</span> <span style="color: blue">class</span> <span style="color: #2b91af">PkgCmdIDList</span></p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">const</span> <span style="color: blue">uint</span> cmdidBuiltInUIContext =&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0&#215;100;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <strong><span style="color: blue">public</span> <span style="color: blue">const</span> <span style="color: blue">uint</span> cmdidQueryStatus&#160;&#160;&#160;&#160;&#160; =&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0&#215;101;</strong></p>
<p style="margin: 0px; text-align: left">};</p>
</p></div>
<p>So that was fairly simple, but obviously we haven&#8217;t registered it with Visual Studio, so there&#8217;s no way the Visual Studio shell will know about this menu command. To do so, we need to make some amendments to the .vsct file. The first of these changes is to identify the new menu command GUID and ID pair in the Symbols section, so that we can reference it elsewhere. This is also easy to do and requires a few lines of XML, which can be added as any first-level child of the Symbols node:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;</span><span style="color: #a31515">GuidSymbol</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSetPart2</span>&quot;<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>&quot;<span style="color: blue">{9d9046da-94f8-4fd0-8a00-92bf4f6defa8}</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">IDSymbol</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">menuidQueryStatusGroup</span>&quot;<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;1020</span>&quot;<span style="color: blue">/&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">IDSymbol</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">cmdidQueryStatus</span>&quot;<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;0101</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;/</span><span style="color: #a31515">GuidSymbol</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>As you can see, this information is based directly off the two previous steps. The &quot;guidDynamicMenuDevelopmentCmdSetPart2&quot; command set has the same GUID as in our GuidList class, and the &quot;cmdidQueryStatus&quot; menu command ID has the same value as in the PkgCmdIDList class.</p>
<p>Our objective is to show this menu command when we right click on DBML files in the designer; this means we&#8217;ll need to create a new Group element whose parent is the Solution Explorer&#8217;s context menu. Then we&#8217;ll need to create a Button element to put in that Group, which represents the menu command itself. This doesn&#8217;t seem like such a problem, until you try to define the Group&#8217;s parent&#8230;</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;</span><span style="color: #a31515">Group</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSetPart2</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">menuidQueryStatusGroup</span>&quot;<span style="color: blue"> </span><span style="color: red">priority</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;001</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span>&#160; &lt;</span><span style="color: #a31515">Parent</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">???</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">???</span>&quot;<span style="color: blue">/&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;/</span><span style="color: #a31515">Group</span><span style="color: blue">&gt;</span></p>
</p></div>
<p><strong>What goes in the place of the question marks?</strong> Well, we might be able to find it in one of the copious header files that sits in the Visual Studio SDK&#8217;s VisualStudioIntegrationCommonInc directory, but I&#8217;m willing to bet that there&#8217;s a faster way. And it turns out there is. Looking at <a href="http://blogs.msdn.com/dr._ex/archive/2007/04/17/using-enablevsiplogging-to-identify-menus-and-commands-with-vs-2005-sp1.aspx">Dr. eX&#8217;s blog entry on VSIPLogging</a> reveals that a simple registry key will allow you see to the GUID:ID pair of almost any menu command in Visual Studio, including those developed by third parties. Changing this setting in the registry and relaunching Visual Studio allows us to check what the GUID and the ID we need are; as it turns out, holding the Ctrl+Shift keys down and right clicking on a project item in the Solution Explorer gives us the information we need:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image5.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="251" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb5.png" width="393" border="0" /></a></p>
<p>We can use this information to fill in the Parent&#8217;s details, but we&#8217;ll need to register the GUID and CmdID in the GuidSymbols element in our .vsct file first.</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">GuidSymbol</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidSolutionExplorerMenu</span>&quot;<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>&quot;<span style="color: blue">{D309F791-903F-11D0-9EFC-00A0C911004F}</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">IDSymbol</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">menuidSolutionExplorerMenu</span>&quot;<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>&quot;<span style="color: blue">1072</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">GuidSymbol</span><span style="color: blue">&gt;</span></p>
</p></div>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;</span><span style="color: #a31515">Group</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSetPart2</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">menuidQueryStatusGroup</span>&quot;<span style="color: blue"> </span><span style="color: red">priority</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;01</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Parent</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">{D309F791-903F-11D0-9EFC-00A0C911004F}</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">1072</span>&quot;<span style="color: blue">/&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;/</span><span style="color: #a31515">Group</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>The Button element isn&#8217;t too exciting by comparison; in fact it doesn&#8217;t differ much from the Button element from the last tutorial. I include it here for reference:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;</span><span style="color: #a31515">Button</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSetPart2</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">cmdidQueryStatus</span>&quot;<span style="color: blue"> </span><span style="color: red">priority</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;0</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">Button</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Parent</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSetPart2</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">menuidQueryStatusGroup</span>&quot;<span style="color: blue">/&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Icon</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidImages</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">bmpPic2</span>&quot;<span style="color: blue">/&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">CommandFlag</span><span style="color: blue">&gt;</span>DynamicVisibility<span style="color: blue">&lt;/</span><span style="color: #a31515">CommandFlag</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Strings</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CommandName</span><span style="color: blue">&gt;</span>cmdidQueryStatus<span style="color: blue">&lt;/</span><span style="color: #a31515">CommandName</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">ButtonText</span><span style="color: blue">&gt;</span>Query Status<span style="color: blue">&lt;/</span><span style="color: #a31515">ButtonText</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">Strings</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;/</span><span style="color: #a31515">Button</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>OK, that&#8217;s it for the .vsct edits. Notice that our Button element still has the &quot;DynamicVisibility&quot; flag, but we have not specified a visibility constraint; this is because we will handle the changes ourselves in procedural code. The final thing we have to do to finish the &quot;plumbing&quot; work by creating our menu command and an event handler to handle its invocation. I&#8217;ll add this code in the DynamicMenuDevelopmentPackage.cs file in the Initialize method. If you navigate there, you&#8217;ll see the wizard-generated code for the first menu command. It&#8217;s only a few lines of code to hook everything together with our second menu command:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">protected</span> <span style="color: blue">override</span> <span style="color: blue">void</span> Initialize()</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #2b91af">Trace</span>.WriteLine (<span style="color: blue">string</span>.Format(<span style="color: #2b91af">CultureInfo</span>.CurrentCulture, <span style="color: #a31515">&quot;Entering Initialize() of: {0}&quot;</span>, <span style="color: blue">this</span>.ToString()));</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: blue">base</span>.Initialize();</p>
<p style="margin: 0px; text-align: left">&#160;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: green">// Add our command handlers for menu (commands must exist in the .vsct file)</span></p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: #2b91af">OleMenuCommandService</span> mcs = GetService(<span style="color: blue">typeof</span>(<span style="color: #2b91af">IMenuCommandService</span>)) <span style="color: blue">as</span> <span style="color: #2b91af">OleMenuCommandService</span>;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: blue">if</span> ( <span style="color: blue">null</span> != mcs )</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; {</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Create the command for the menu item.</span></p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">CommandID</span> menuCommandID = <span style="color: blue">new</span> <span style="color: #2b91af">CommandID</span>(<span style="color: #2b91af">GuidList</span>.guidDynamicMenuDevelopmentCmdSet, (<span style="color: blue">int</span>)<span style="color: #2b91af">PkgCmdIDList</span>.cmdidBuiltInUIContext);</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">MenuCommand</span> menuItem = <span style="color: blue">new</span> <span style="color: #2b91af">MenuCommand</span>(MenuItemCallback, menuCommandID );</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; mcs.AddCommand( menuItem );</p>
<p style="margin: 0px; text-align: left">&#160;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Create the command for the query status menu item.</span></p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">CommandID</span> queryStatusCommandID = <span style="color: blue">new</span> <span style="color: #2b91af">CommandID</span>(<span style="color: #2b91af">GuidList</span>.guidDynamicMenuDevelopmentCmdSetPart2, (<span style="color: blue">int</span>)<span style="color: #2b91af">PkgCmdIDList</span>.cmdidQueryStatus);</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">OleMenuCommand</span> queryStatusMenuCommand = <span style="color: blue">new</span> <span style="color: #2b91af">OleMenuCommand</span>(MenuItemCallback, queryStatusCommandID);</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; mcs.AddCommand(queryStatusMenuCommand);</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; }</p>
<p style="margin: 0px; text-align: left">}</p>
</p></div>
<p>One thing to note here is that in contrast to the first menu command, we are creating an OleMenuCommand, not a regular MenuCommand. The reasons will become apparent later, but for now, let&#8217;s press F5 to see what we&#8217;ve got. Open an existing solution (or create a new one if it&#8217;s easier to do so) and right click on a project item (not a folder, project, or solution node, though) and you will see our &quot;Query Status&quot; command:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image6.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="317" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb6.png" width="312" border="0" /></a></p>
<h3 style="margin-bottom: 10px">Step 2: Making It Dynamic</h3>
<p>As expected, though, it shows up regardless of the selected item in the project, so we haven&#8217;t reached the end yet! Going back to the code in DynamicMenuDevelopmentPackage, we discover a use for the OleMenuCommand vs. the MenuCommand. The OleMenuCommand exposes an event called BeforeQueryStatus, which is raised right before Visual Studio asks what the state of a particular menu item is. In this case, it&#8217;s a perfect place to edit the state of our menu command based on the current selection in the Solution Explorer. Adding the following event handler to the BeforeQueryStatus event of that OleMenuCommand helps us achieve our desired goal:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">private</span> <span style="color: blue">void</span> queryStatusMenuCommand_BeforeQueryStatus(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: #2b91af">OleMenuCommand</span> menuCommand = sender <span style="color: blue">as</span> <span style="color: #2b91af">OleMenuCommand</span>;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: blue">if</span> (menuCommand != <span style="color: blue">null</span>)</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; {</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">IntPtr</span> hierarchyPtr, selectionContainerPtr;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">uint</span> projectItemId;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">IVsMultiItemSelect</span> mis;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">IVsMonitorSelection</span> monitorSelection = (<span style="color: #2b91af">IVsMonitorSelection</span>)<span style="color: #2b91af">Package</span>.GetGlobalService(<span style="color: blue">typeof</span>(<span style="color: #2b91af">SVsShellMonitorSelection</span>));</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; monitorSelection.GetCurrentSelection(<span style="color: blue">out</span> hierarchyPtr, <span style="color: blue">out</span> projectItemId, <span style="color: blue">out</span> mis, <span style="color: blue">out</span> selectionContainerPtr);</p>
<p style="margin: 0px; text-align: left">&#160;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">IVsHierarchy</span> hierarchy = <span style="color: #2b91af">Marshal</span>.GetTypedObjectForIUnknown(hierarchyPtr, <span style="color: blue">typeof</span>(<span style="color: #2b91af">IVsHierarchy</span>)) <span style="color: blue">as</span> <span style="color: #2b91af">IVsHierarchy</span>;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (hierarchy != <span style="color: blue">null</span>)</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">object</span> value;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; hierarchy.GetProperty(projectItemId, (<span style="color: blue">int</span>)<span style="color: #2b91af">__VSHPROPID</span>.VSHPROPID_Name, <span style="color: blue">       <br  ="><br   " />&gt;out</span> value);</p>
<p style="margin: 0px; text-align: left">&#160;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (value != <span style="color: blue">null</span> &amp;&amp; value.ToString().EndsWith(<span style="color: #a31515">&quot;.dbml&quot;</span>))</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; menuCommand.Visible = <span style="color: blue">true</span>;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span></p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; menuCommand.Visible = <span style="color: blue">false</span>;</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; }</p>
<p style="margin: 0px; text-align: left">}</p>
</p></div>
<p>I won&#8217;t explain all the code here, but the gist is that we are getting the name of the current selection, checking if it ends with the &quot;.dbml&quot; extension, and dynamically setting the visibility on our menu command based on that result. Unfortunately, this is <em>still</em> not enough to correctly implement our dynamic menu command, due to the fact that Visual Studio loads packages <em><a href="http://architekturaforum.hu/blogs/divedeeper/archive/2008/01/11/LearnVSXNowPart5.aspx">on demand</a>.</em> To make a long story short, the code that we just wrote to handle dynamic menu item visibility will be called only when the package is loaded, and the package is loaded only when some UI element exposed by the package is clicked, which invokes some piece of code in the underlying package. This does not really help us when all the package exposes is two menu commands!</p>
<p>This is a problem that I encountered recently, and consequently I am open to any suggestions. My solution has been to put the ProvideAutoLoadAttribute on the class, which tells Visual Studio to load the package automatically when it encounters a certain UI context. In this circumstance, the context &quot;UICONTEXT_SolutionExists&quot; (defined in vsshlids.h) suits our purposes perfectly. We&#8217;ll have to specify the GUID itself instead of its alias, however, like this:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left">[<span style="color: #2b91af">ProvideAutoLoad</span>(<span style="color: #a31515">&quot;{f1536ef8-92ec-443c-9ed7-fdadf150da82}&quot;</span>)]</p>
<p style="margin: 0px; text-align: left"><span style="color: blue">public</span> <span style="color: blue">sealed</span> <span style="color: blue">class</span> <span style="color: #2b91af">DynamicMenuDevelopmentPackage</span> : <span style="color: #2b91af">Package</span></p>
<p style="margin: 0px; text-align: left">{</p>
<p style="margin: 0px; text-align: left">&#160;&#160;&#160; <span style="color: green">// &#8230;</span></p>
<p style="margin: 0px; text-align: left">}</p>
</p></div>
<p>And that&#8217;s it! Press F5 and open a solution to see for yourself. The &quot;Query Status&quot; command will appear only when right-clicking on .dbml files in the Solution Explorer.</p>
<h3><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/dynamicmenudevelopment-part-2.zip">Associated Solution</a></h3>
<h4>Other Articles in the Series</h4>
<ul>
<li><a href="http://blogs.rev-net.com/ddewinter/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/">Part 1 &#8211; Using UI Contexts</a> </li>
<li><a href="http://blogs.rev-net.com/ddewinter/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/">Part 3 &#8211; Custom UI Contexts</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Dynamic Menu Commands in Visual Studio Packages &#8211; Part 1</title>
		<link>http://davedewinter.com/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/</link>
		<comments>http://davedewinter.com/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 14:14:02 +0000</pubDate>
		<dc:creator>David DeWinter</dc:creator>
				<category><![CDATA[DBML Fixup]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>
		<category><![CDATA[VSX]]></category>

		<guid isPermaLink="false">http://blogs.rev-net.com/ddewinter/?p=62</guid>
		<description><![CDATA[As I get further into my DBML Fixup project, I&#8217;m learning more and more about Visual Studio Extensibility (VSX). Along the way, I have found multiple blogs which have helped me to learn a lot more than I would than &#8230; <a href="http://davedewinter.com/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As I get further into my <a href="http://blogs.rev-net.com/ddewinter/?p=41">DBML Fixup</a> project, I&#8217;m learning more and more about Visual Studio Extensibility (VSX). Along the way, I have found multiple blogs which have helped me to learn a lot more than I would than just stepping through the documentation. (Those blogs are now listed on the sidebar.) The one I find especially helpful for beginners like me is <a href="http://www.architekturaforum.hu/blogs/divedeeper/default.aspx">DiveDeeper</a>, whose LearnVSXNow tutorials are great stepping stones in learning the basics of VSX Packages. He currently has 14 tutorials, the first of which is located <a href="http://www.architekturaforum.hu/blogs/divedeeper/archive/2008/01/02/LearnVSXNowPart1.aspx">here</a>. Although his blog is very helpful for learning about how to work with menu commands, he hasn&#8217;t (yet?) delved into making them dynamic. I needed to do this for my project, so I had to &quot;dive deeper,&quot; as it were.</p>
<p>In this series of posts I&#8217;m going to focus on three ways to make menu commands <em>dynamic</em>—that is, how to make menu commands invisible or disabled in certain contexts, but visible and enabled in others. Two of these ways I found through some experimentation. Consequently, I&#8217;m not sure whether these represent VSX best practices, so if anyone has any more input, it would be greatly appreciated. With that said, let&#8217;s get started.</p>
</p>
<p> <span id="more-85"></span>
</p>
<h3>Using a Built-In UI Context</h3>
<p>For each of these techniques, I&#8217;ll be using the same solution, and I&#8217;ll post the solution with the current progress at the end of each post. But&#8230;first things first: create a new project and select the Visual Studio Integration Package project type.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="574" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb.png" width="808" border="0" /></a></p>
<p>The Visual Studio Integration Package Wizard pops up. For this tutorial we&#8217;ll use Visual C# and generate a new key file to sign the assembly.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image1.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="386" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb1.png" width="510" border="0" /></a></p>
<p>For the basic information page, feel free to type whatever you want for the company name, package name, and detailed information. I&#8217;ll leave the minimum Visual Studio edition at &quot;Standard,&quot; as well. On the next page, check the Menu Command check box to indicate to the wizard that we want to, of course, make a menu command.</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image2.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="386" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb2.png" width="510" border="0" /></a></p>
<p>We&#8217;ll provide the following command name and ID for the command the wizard will generate:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image3.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="386" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb3.png" width="510" border="0" /></a></p>
<p>On the last page, uncheck the Integration Test Project and Unit Test Project options, as we won&#8217;t need these for this demonstration. If you are interested in the Integration Test and Unit Test options, have a look at <a href="http://www.architekturaforum.hu/blogs/divedeeper/archive/2008/02/07/LearnVSXNowPart11.aspx">this blog entry</a>. Click &quot;Finish,&quot; and the wizard will create the majority of the solution for us. Press F5 and verify that a &quot;Built In UI Context&quot; menu item appears in the Tools menu:</p>
<p><a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image4.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="141" alt="image" src="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/image-thumb4.png" width="326" border="0" /></a></p>
<p>The integration package wizard has gotten us this far, but we have to supply the finishing touches in order to make this menu item dynamic. In order to do this we need a little background in the .vsct file&#8217;s structure. There should be one in your project (DynamicMenuDevelopment.vsct in my case). Go ahead and open that file. The following will briefly touch on the different points of the .vsct file. If you don&#8217;t have any previous experience working with these, please read <a href="http://www.architekturaforum.hu/blogs/divedeeper/archive/2008/03/02/LearnVSXNowPart14.aspx">this excellent post</a> before continuing.</p>
<p>In the VSCT file, our menu command is represented by the sole Button element:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 15px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Button</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSet</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">cmdidBuiltInUIContext</span>&quot;<span style="color: blue"> </span><span style="color: red">priority</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;0100</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">Button</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Parent</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSet</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">MyMenuGroup</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Icon</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidImages</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">bmpPic1</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Strings</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CommandName</span><span style="color: blue">&gt;</span>cmdidBuiltInUIContext<span style="color: blue">&lt;/</span><span style="color: #a31515">CommandName</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">ButtonText</span><span style="color: blue">&gt;</span>Built In UI Context<span style="color: blue">&lt;/</span><span style="color: #a31515">ButtonText</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">Strings</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Button</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>That &quot;button&quot; is parented by the &quot;MyMenuGroup&quot; group element:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 15px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Group</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSet</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">MyMenuGroup</span>&quot;<span style="color: blue"> </span><span style="color: red">priority</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;0600</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Parent</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidSHLMainMenu</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">IDM_VS_MENU_TOOLS</span>&quot;<span style="color: blue">/&gt;</span></p>
<p><span style="color: blue">&lt;/</span><span style="color: #a31515">Group</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>And that group is parented by the Tools menu. If we look at the GuidSymbols element in the file, we can see the GUIDs for our package, guidDynamicMenuDevelopmentPkg, as well as our set of commands, guidDynamicMenuDevelopmentCmdSet. The latter has some IDs which identify the single menu command and the group: cmdidBuiltInUIContext and MyMenuGroup, respectively. But if you look at the Group&#8217;s parent in the previous XML snippet, you&#8217;ll see a GUID guidSHLMainMenu and an ID IDM_VS_MENU_TOOLS which are not defined here. Where do they come from? They are defined externally in the vsshlids.h, which we &quot;imported&quot; using one of the Extern elements at the beginning of the document.</p>
<p>From here, it&#8217;s very simple to add dynamic visibility. Navigate back to the Button element and add the CommandFlag element, as demonstrated below:</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: blue">&lt;</span><span style="color: #a31515">Button</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSet</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">cmdidBuiltInUIContext</span>&quot;<span style="color: blue"> </span><span style="color: red">priority</span><span style="color: blue">=</span>&quot;<span style="color: blue">0&#215;0100</span>&quot;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">Button</span>&quot;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Parent</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSet</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">MyMenuGroup</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Icon</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidImages</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">bmpPic1</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; <strong>&lt;</strong></span><strong><span style="color: #a31515">CommandFlag</span><span style="color: blue">&gt;</span>DynamicVisibility<span style="color: blue">&lt;/</span><span style="color: #a31515">CommandFlag</span><span style="color: blue">&gt;</span></strong></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Strings</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">CommandName</span><span style="color: blue">&gt;</span>cmdidBuiltInUIContext<span style="color: blue">&lt;/</span><span style="color: #a31515">CommandName</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">ButtonText</span><span style="color: blue">&gt;</span>Built In UI Context<span style="color: blue">&lt;/</span><span style="color: #a31515">ButtonText</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">Strings</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: blue">&lt;/</span><span style="color: #a31515">Button</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>Simple, right? We&#8217;ve told Visual Studio that this command may be invisible at times and visible at other times, but we haven&#8217;t told it when. To do that, we must add a VisibilityConstraints element underneath the closing Commands tag.</p>
<div style="font-size: 8pt; background: white; margin-bottom: 10px; color: black; font-family: courier new">
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;</span><span style="color: #a31515">VisibilityConstraints</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">VisibilityItem</span><span style="color: blue"> </span><span style="color: red">guid</span><span style="color: blue">=</span>&quot;<span style="color: blue">guidDynamicMenuDevelopmentCmdSet</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">cmdidBuiltInUIContext</span>&quot;<span style="color: blue"> </span><span style="color: red">context</span><span style="color: blue">=</span>&quot;<span style="color: blue">UICONTEXT_NoSolution</span>&quot;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px; text-align: left"><span style="color: blue">&lt;/</span><span style="color: #a31515">VisibilityConstraints</span><span style="color: blue">&gt;</span></p>
</p></div>
<p>If you think about it, you can make some educated guesses about what this piece of the XML says. The VisibilityItem element specifies the same GUID and ID pair as our Button element above, so they must be related. Furthermore, the element specifies a context attribute which we have not seen before. This is the sole part of the VSCT file that tells Visual Studio <em>when</em> a particular command is visible or invisible. You can also infer that UICONTEXT_NoSolution means that the menu command will be visible only when there is no solution open. Press F5 and try it!</p>
<p>That leaves one last question before wrapping up this technique, and that is &quot;Where is UICONTEXT_NoSolution defined?&quot; It certainly isn&#8217;t in our GuidSymbols, but if you remember we have a couple of external header files that we reference. One of those is vsshlids.h. If you navigate to the %PROGRAMFILES%Microsoft Visual Studio 2008 SDKVisualStudioIntegrationCommonInc directory, you&#8217;ll find vsshlids.h among a multitude of other header files. If you open that file and search for &quot;UICONTEXT_&quot;, you&#8217;ll see a couple of different contexts, including UICONTEXT_NoSolution. You can use any of the other UI Contexts in this file in order to control dynamic visibility for your menu command.</p>
<p>That was pretty good for writing only a few lines of XML, but if there&#8217;s no built-in UI context that fits your requirements, then this solution will not work for you. Also, this technique works only for hiding and show menu commands, not for disabling and enabling them. In short, while it&#8217;s fairly easy to do, it&#8217;s sometimes not flexible enough for the job.</p>
<p>Next time I&#8217;ll outline another technique, which is also fairly simple, but requires us to write some code. Hope this helps you in your VSX development!</p>
<p>Edit: I realize I forgot to post the solution for this example! It is a Visual Studio 2008 solution and it&#8217;s located <a href="http://blogs.rev-net.com/ddewinter/wp-content/uploads/2008/03/dynamicmenudevelopment-part-1.zip">here</a>.</p>
<h4>Other Articles in the Series</h4>
<ul>
<li><a href="http://blogs.rev-net.com/ddewinter/index.php/2008/03/22/dynamic-menu-commands-in-visual-studio-packages-part-2/">Part 2 &#8211; The BeforeQueryStatus Event</a> </li>
<li><a href="http://blogs.rev-net.com/ddewinter/index.php/2008/04/05/dynamic-menu-commands-in-visual-studio-packages-part-3/">Part 3 &#8211; Custom UI Contexts</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davedewinter.com/2008/03/14/dynamic-menu-commands-in-visual-studio-packages-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

