<?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>Huddled Masses &#187; GUI</title>
	<atom:link href="http://joelbennett.net/tag/gui/feed/" rel="self" type="application/rss+xml" />
	<link>http://joelbennett.net</link>
	<description>The internet home of Joel "Jaykul" Bennett...</description>
	<lastBuildDate>Sat, 28 Jan 2012 21:37:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<cloud domain='joelbennett.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Did you know PowerShell can use Selenium?</title>
		<link>http://joelbennett.net/did-you-know-powershell-can-use-selenium/</link>
		<comments>http://joelbennett.net/did-you-know-powershell-can-use-selenium/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 05:46:42 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[WatiN]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1789</guid>
		<description><![CDATA[This is sort-of a place-holder for a full-length post that I really ought to write about driving web testing from PowerShell using Selenium. I actually have a little module around for doing that with WaTiN, but honestly the Selenium project seems to be a lot more active, and has quite a bit of muscle behind [...]]]></description>
			<content:encoded><![CDATA[	<p>This is sort-of a place-holder for a full-length post that I really ought to write about driving web testing from PowerShell using Selenium.  I actually have a little module around for doing that with WaTiN, but honestly the Selenium project seems to be a lot more active, and has quite a bit of muscle behind it since they&#8217;ve merged with WebDriver&#8230;</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Type</span></span> <span style="color: #000066;">-path</span> ~\Downloads\selenium<span style="color: #66cc66;">-</span>dotnet<span style="color: #66cc66;">-</span>2.16.0\net40\WebDriver.<span style="color: #003366;">dll</span> <br />
<br />
<span style="color: #666666; font-style: italic;"># Navigate to google in IE (or Firefox, Chrome, Opera, etc)</span><br />
<span style="color: #660033; font-weight: bold;">$driver</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> OpenQA.<span style="color: #003366;">Selenium</span>.<span style="color: #003366;">IE</span>.<span style="color: #003366;">InternetExplorerDriver</span> <br />
<span style="color: #660033; font-weight: bold;">$driver</span>.<span style="color: #003366;">Url</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;http://google.com&quot;</span><br />
<br />
<span style="color: #666666; font-style: italic;"># Type PowerShell into the query box, the page will update via AJAX</span><br />
<span style="color: #666666; font-style: italic;"># Note we won't hit enter or anything</span><br />
<span style="color: #660033; font-weight: bold;">$q</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$driver</span>.<span style="color: #003366;">FindElementByname</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;q&quot;</span><span style="color: #333;">&#41;</span> <br />
<span style="color: #660033; font-weight: bold;">$q</span>.<span style="color: #003366;">SendKeys</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;PowerShell&quot;</span><span style="color: #333;">&#41;</span> <br />
<br />
<span style="color: #666666; font-style: italic;"># Use a CSS selector to find the first result link and click it</span><br />
<span style="color: #660033; font-weight: bold;">$driver</span>.<span style="color: #003366;">FindElementByCssSelector</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;li.g h3.r a&quot;</span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">Click</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp;</div>

	<h3>One Catch</h3>

	<p><a href="http://joelbennett.net/wordpress/wp-content/uploads/2012/01/ProtectedMode.png" style="float:right; padding-left: 1em; "><img src="http://joelbennett.net/wordpress/wp-content/uploads/2012/01/ProtectedMode.png" alt="The Security tab of the Internet Options dialog" title="ProtectedMode" width="423" height="541" class="size-full wp-image-1796" /></a>If you try this with IE and you get the error <em>Unexpected error launching Internet Explorer. Protected Mode must be set to the same value (enabled or disabled) for all zones</em> ... it means exactly what it says.  You need to open &#8220;Internet Options&#8221; from your start menu (or from IE), and go through each &#8220;zone&#8221; and set the &#8220;Enabled Protected Mode&#8221; check box to the same value for each zone (either all checked, obviously the most secure, or all unchecked).  I&#8217;m not going to debate whether setting them all <em>unprotected</em> is a good idea &#8230; I set mine to all protected, but I don&#8217;t generally use IE anyway. </p>

	<p>If you want more help, Selenium&#8217;s documentation is great, and there&#8217;s a section on <a href="http://seleniumhq.org/docs/03_webdriver.html#getting-started-with-selenium-webdriver">Getting Started with Selenium WebDriver</a> which I found quite helpful (make sure your examples are in &#8220;csharp&#8221; and you can almost just copy and paste &#8212; someone should offer to do them in PowerShell).  </p>

	<p>If you want more information about the Internet Explorer driver and this problem in particular, the short answer is that &#8220;Protected Mode&#8221; is a security boundry, so if you cross over it the <span class="caps">COM</span> automation object doesn&#8217;t work &#8212; thus, you need to make sure you always stay on the same side. There&#8217;s a good discussion <a href="http://code.google.com/p/selenium/issues/detail?id=1795">on the mailing list archive</a> about how it works and why, as well a weird alternative <a href="http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/ie/InternetExplorerDriver.html#INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS">documented on the Selenium JavaDocs</a></p>]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/did-you-know-powershell-can-use-selenium/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PowerBoots: The tutorial walkthrough</title>
		<link>http://joelbennett.net/powerboots-tutorial-walkthrough/</link>
		<comments>http://joelbennett.net/powerboots-tutorial-walkthrough/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 16:21:13 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[PowerBoots]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerTips]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[WalkThrough]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=963</guid>
		<description><![CDATA[Updated to PowerBoots 0.1 An introduction to PowerBoots Please excuse me if I start by just copying the basic ideas of the Shoes Tutorial, but I figured that since PowerBoots is inspired by Shoes, that was as good a place as any to start. PowerBoots (or just &#8220;Boots&#8221;) is a PowerShell 2.0 module with functions [...]]]></description>
			<content:encoded><![CDATA[	<h3> <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  Updated to PowerBoots 0.1</h3>

	<h2>An introduction to PowerBoots</h2>

	<p>Please excuse me if I start by just copying the basic ideas of the <a href="http://shoooes.net/tutorial/">Shoes Tutorial</a>, but I figured that since PowerBoots is inspired by Shoes, that was as good a place as any to start.  PowerBoots (or just &#8220;Boots&#8221;) is a PowerShell 2.0 module with functions for writing Windows Presentation Framework (<span class="caps">WPF</span>) applications in the PowerShell scripting language.  You should get <a href="http://boots.CodePlex.com">the latest version of PowerBoots</a> before continuing, and install it by putting the &#8220;PowerBoots&#8221; folder in one of your &#8220;Modules&#8221; folders (list them by typing <code>$Env:PSMODULEPATH</code> in PowerShell v2). </p>

	<p><del>Don&#8217;t forget to start PowerShell.exe with the <span class="caps">STA</span> parameter</del> (This is no longer required in PowerBoots 0.1).</p>

	<p>Did I hear someone ask <strong>what <em>is</em> WPF?</strong> It was introduced as part of .Net 3.0 (and vastly improved in .Net 3.5), so you can expect to find it preinstalled on computers from Vista on, and of course you can download and install it on XP if it&#8217;s not already installed.  The only thing you really need to know about <span class="caps">WPF</span> for the purposes of this tutorial is that it is <strong>the</strong> new <span class="caps">GUI</span> toolkit for .Net, and that it is container based &#8212; you put elements into other elements to control the layout, rather like <span class="caps">HTML</span> and Java Swing&#8230; you can <strong>pick up the rest as we go along</strong>.</p>

	<h2>A simple Boots program</h2>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots1.png" class="float-right-block" alt="" width="144" height="86" /></p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">BootsWindow</span></span> <span style="color: #000066;">-SizeToContent</span> WidthAndHeight <span style="color: #000066;">-Content</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;Button <span style="color: #000066;">-Content</span> <span style="color: #009900;">&quot;Push Me&quot;</span> <br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>I&#8217;ve recently <strong>changed</strong> this first example to pass a script block to the content instead of using parentheses, because although PowerBoots supports running in an <span class="caps">MTA</span> PowerShell host, the only UI-creation command that is MTA-safe is the New-BootsWindow command. All of the &#8220;new&#8221; functions must then be inside of a scriptblock which is passed to the New-BootsWindow cmdlet and executed on that <span class="caps">STA</span> thread. You can use parenthesis ( and ) as a container instead, but that requires the host to be in <span class="caps">STA</span> threading mode (run: PowerShell -<span class="caps">STA</span>) so the controls can be created:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">BootsWindow</span></span> <span style="color: #000066;">-SizeToContent</span> WidthAndHeight <span style="color: #000066;">-Content</span> <span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp;Button <span style="color: #000066;">-Content</span> <span style="color: #009900;">&quot;Push Me&quot;</span><br />
<span style="color: #333;">&#41;</span><br />
&nbsp;</div>

	<p>This first example is a bit uglier than the Shoes syntax, so lets see if we can&#8217;t clean it up some. The <code>-Content</code> parameter is positional, so the first non-named argument you pass will be used for that. The same is true for the -Children parameter of panels, and in fact, each of the other similar parameters: Items, Blocks, and Inlines.</p>

	<p>We have used a function <code>New-BootsWindow</code> which has an alias <code>Boots</code>. Boots takes all the same parameters as the <code>Window</code> function mentioned previously, but it uses slightly more useful defaults, and has a few other major benefits as well, the first of which is that it automatically &#8220;shows&#8221; the window, and the second is that it supports an <code>-Async</code> parameter which allows the window to come out in a new thread so that you can continue using PowerShell while the window remains alive and responsive.  There is one catch: New-BootsWindow <em>cannot</em> take it&#8217;s content on the pipeline (the <em>old function</em>, now renamed &#8220;Out-BootsWindow&#8221; can take pipeline content, but is a script function, and requires -<span class="caps">STA</span> mode) &#8212; you have to specify it as a ScriptBlock. So now that we know this, we can rewrite our first example like this:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span> Button <span style="color: #009900;">&quot;Push Me&quot;</span> <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>Just for the record, the simplest Boots program would just be a simple popup dialog to put some text in a Window, like:  <code>Boots { $msg }</code> &#8230;</p>

	<h2>We can put controls in a stack</h2>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots2.png" class="float-right-block" alt="" width="156" height="128" /></p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;StackPanel <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #009900;">&quot;A bed of clams&quot;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #009900;">&quot;A coalition of cheetas&quot;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #009900;">&quot;A gulp of swallows&quot;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>StackPanels are awesome. So are WrapPanels.  Try that code with a WrapPanel instead of a StackPanel and see what the difference is.  This brings up another point: those positional parameters we mentioned earlier: Content, Children, Items, Blocks, and Inlines, are also set to accept the value from the pipeline.  Not only that, but they are intelligent about whether or not the content model accepts multiple items! So we can actually rewrite that script like this, and get the same results:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span> <span style="color: #009900;">&quot;A bed of clams&quot;</span>, <span style="color: #009900;">&quot;A coalition of cheetas&quot;</span>, <span style="color: #009900;">&quot;A gulp of swallows&quot;</span> <span style="color: #66cc66;">|</span> Button <span style="color: #66cc66;">|</span> StackPanel <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>Now we&#8217;re really onto something! <span id="more-963"></span> For most of the rest of these examples, I&#8217;m going to stick with the former syntax, because with the indenting and parenthesis, it&#8217;s much easier for you to follow, especially if you&#8217;re not already familiar with <span class="caps">WPF</span>.  For instance, check out what this does:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span> <span style="color: #009900;">&quot;A bed of clams&quot;</span>, <span style="color: #009900;">&quot;A coalition of cheetas&quot;</span>, <span style="color: #009900;">&quot;A gulp of swallows&quot;</span> <span style="color: #66cc66;">|</span> StackPanel <span style="color: #66cc66;">|</span> Button <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<h2>Ok, lets see some formatting</h2>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots3.png" class="float-right-block" alt="" width="174" height="152" /></p>

	<p>To scoot the buttons out from the edge we can use margins or padding: margins go on the outside of containers, padding goes on the inside.</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;StackPanel <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">5</span> <span style="color: #000066;">-Background</span> Pink $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&quot;A bed of clams&quot;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&quot;A coalition of cheetas&quot;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&quot;A gulp of swallows&quot;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Or, on one line:</span><br />
<br />
Boots <span style="color: #333;">&#123;</span> <span style="color: #009900;">&quot;A bed of clams&quot;</span>, <span style="color: #009900;">&quot;A coalition of cheetas&quot;</span>, <span style="color: #009900;">&quot;A gulp of swallows&quot;</span> <span style="color: #66cc66;">|</span><br />
&nbsp; &nbsp;Button <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">|</span> StackPanel <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">5</span> <span style="color: #000066;">-Background</span> Pink <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>So you see, the pink background is on the StackPanel, which has a (white) margin around it.  If you wanted the whole background of the window to be pink, you would need to set the background of the Window instead of the StackPanel.</p>

	<h2>Time for some artwork</h2>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots4.png" class="float-right-block" alt="" width="176" height="164" /></p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span> Ellipse <span style="color: #000066;">-Width</span> <span style="color: #cc66cc;">60</span> <span style="color: #000066;">-Height</span> <span style="color: #cc66cc;">80</span> <span style="color: #000066;">-Margin</span> <span style="color: #009900;">&quot;20,10,60,20&quot;</span> <span style="color: #000066;">-Fill</span> Black <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>In Boots, everything always starts out white, and you must position things based on the container. You can see that the Margin can be specified as a single value as in the previous example, or as separate values for Left, Top, Right, Bottom.  Oddly, to satisfy PowerShell&#8217;s type-casting, you have to quote them so they&#8217;re a single comma-separated string, instead of four separate values.</p>

	<h2>Some more advanced drawing</h2>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots5.png" class="float-right-block" alt="" width="148" height="158" /></p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span><br />
Canvas <span style="color: #000066;">-Height</span> <span style="color: #cc66cc;">100</span> <span style="color: #000066;">-Width</span> <span style="color: #cc66cc;">100</span> <span style="color: #000066;">-Children</span> $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp;Rectangle <span style="color: #000066;">-Margin</span> <span style="color: #009900;">&quot;10,10,0,0&quot;</span> <span style="color: #000066;">-Width</span> <span style="color: #cc66cc;">45</span> <span style="color: #000066;">-Height</span> <span style="color: #cc66cc;">45</span> <span style="color: #000066;">-Stroke</span> Purple <span style="color: #000066;">-StrokeThickness</span> <span style="color: #cc66cc;">2</span> <span style="color: #000066;">-Fill</span> Red<br />
&nbsp; &nbsp;Polygon <span style="color: #000066;">-Stroke</span> Pink <span style="color: #000066;">-StrokeThickness</span> <span style="color: #cc66cc;">2</span> <span style="color: #000066;">-Fill</span> DarkRed <span style="color: #000066;">-Points</span> <span style="color: #009900;">&quot;10,60&quot;</span>, <span style="color: #009900;">&quot;50,60&quot;</span>, <span style="color: #009900;">&quot;50,50&quot;</span>, <span style="color: #009900;">&quot;65,65&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;50,80&quot;</span>, <span style="color: #009900;">&quot;50,70&quot;</span>, <span style="color: #009900;">&quot;10,70&quot;</span>, <span style="color: #009900;">&quot;10,60&quot;</span> <br />
<span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>We use a Canvas for this because it can contain multiple items which are all absolutely positioned.  Unlike other containers, it doesn&#8217;t automatically expand to contain it&#8217;s children, so you typically have to set it&#8217;s size.</p>

	<p>We also have to set the Stroke and Fill.  These are the two colors that make up every object, if we don&#8217;t set them, they default to white. The StrokeThickness controls the line thickness.  Notice that we positioned the Rectangle by using the <code>Margin</code>, and positioned the arrow, which we built using a Polygon, based purely on the x,y coordinates of the points.  The available shapes are Ellipse, Line, Path, Polygon, Polyline, and Rectangle.  You can, of course, make any shape you want to with the Polygon.</p>

	<p>There are other more advanced shapes available in external libraries, and we can even do 3D, use gradient or image fills&#8230;</p>

	<h3>We can even get images straight off the web</h3>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;Image <span style="color: #000066;">-Source</span> http:<span style="color: #66cc66;">//</span>huddledmasses.<span style="color: #003366;">org</span><span style="color: #66cc66;">/</span>images<span style="color: #66cc66;">/</span>PowerBoots<span style="color: #66cc66;">/</span>IMG_3298.<span style="color: #003366;">jpg</span> <span style="color: #000066;">-MaxWidth</span> <span style="color: #cc66cc;">400</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #333;">&#125;</span> <span style="color: #000066;">-Title</span> <span style="color: #009900;">&quot;Now those are some powerful boots!&quot;</span> <span style="color: #000066;">-Async</span><br />
&nbsp;</div>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots6.png" class="float-right-block" alt="" width="436" height="730" /></p>

	<p>Boots loads the image on a background thread, and caches it in memory, so the window will show up and be responsive while you&#8217;re waiting for the image, and because we&#8217;ve specified <code>-Async</code>, you can actually continue using PowerShell while the image loads. Note: it will load much faster the second time you run that script.  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=';)' class='wp-smiley' /> </p>

<h3 style="clear: both;">Typography</h3>

	<p>PowerBoots doesn&#8217;t try to create a full set of typography-specific top-level elements the way Shoes does, because we are based on <span class="caps">WPF</span>, which has a far more powerful typography system available than any we&#8217;ve ever used.  So instead of having a bunch of named elements like banner, and title, and caption, and para and whatnot, we have controls based on how much text you want to put in them, and how much formatting you want to apply: Label is simplest, TextBlock supports limited text formattings, and FlowDocument supports full rich content. And of course, Hyperlink supports clicking  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=';)' class='wp-smiley' /> </p>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots7.png" class="float-right-block" alt="" width="466" height="202" /></p>

	<p>For the typography elements, the content model changes a bit.  There are basically two types: Inline and Block elements. The <a href="http://msdn.microsoft.com/en-us/library/bb613554.aspx">TextBlock Content Model</a> is similar to that of a FlowDocument, it is actually a type-restricted &#8220;Items&#8221; container.  Instead of being able to have <em>anything</em> as content, it can only contain <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.inline.aspx">Inline</a> flow content elements such as <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.anchoredblock.aspx">AnchoredBlock</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.bold.aspx">Bold</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.hyperlink.aspx">Hyperlink</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.inlineuicontainer.aspx">InlineUIContainer</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.italic.aspx">Italic</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.linebreak.aspx">LineBreak</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.run.aspx">Run</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.span.aspx">Span</a>, and <a href="http://msdn.microsoft.com/en-us/library/system.windows.documents.underline.aspx">Underline</a>, and it will create a run automatically if you just put a text string in it. </p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;StackPanel <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">10</span> <span style="color: #000066;">-Children</span> $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; TextBlock <span style="color: #009900;">&quot;A Question&quot;</span> <span style="color: #000066;">-FontSize</span> <span style="color: #cc66cc;">42</span> <span style="color: #000066;">-FontWeight</span> Bold <span style="color: #000066;">-Foreground</span> <span style="color: #009900;">&quot;#FF0088&quot;</span> <br />
&nbsp; &nbsp; &nbsp; TextBlock <span style="color: #000066;">-FontSize</span> <span style="color: #cc66cc;">24</span> <span style="color: #000066;">-Inlines</span> $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Bold <span style="color: #009900;">&quot;Q. &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;Are you starting to dig &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Hyperlink <span style="color: #009900;">&quot;PowerBoots?&quot;</span> <span style="color: #000066;">-NavigateUri</span> http:<span style="color: #66cc66;">//</span>huddledmasses.<span style="color: #003366;">org</span><span style="color: #66cc66;">/</span>tag<span style="color: #66cc66;">/</span>powerboots<span style="color: #66cc66;">/</span> `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">-On_RequestNavigate</span> <span style="color: #333;">&#123;</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Diagnostics.<span style="color: #666699; font-weight: bold;">Process</span><span style="color: #333;">&#93;</span></span>::<span style="color: #660033;">Start</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$this</span>.<span style="color: #003366;">NavigateUri</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; TextBlock <span style="color: #000066;">-FontSize</span> <span style="color: #cc66cc;">16</span> <span style="color: #000066;">-Inlines</span> $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Span <span style="color: #000066;">-FontSize</span> <span style="color: #cc66cc;">24</span> <span style="color: #000066;">-FontWeight</span> Bold <span style="color: #000066;">-Inlines</span> <span style="color: #009900;">&quot;A. &quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;Leave me alone, I'm hacking here!&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>Note: If you want support for the full <a href="http://msdn.microsoft.com/en-us/library/aa970909.aspx">document model</a> (which allows Paragraphs and Lists), you need to use a <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.flowdocumentreader.aspx">FlowDocumentReader</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.flowdocumentpageviewer.aspx">FlowDocumentPageViewer</a>, <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx">RichTextBox</a>, or a <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.flowdocumentscrollviewer.aspx">FlowDocumentScrollViewer</a> ... there&#8217;s lots more information about those <a href="http://msdn.microsoft.com/en-us/library/aa970909.aspx">on msdn</a>.</p>

	<h3>Events</h3>

	<p>If you were paying attention to that previous example, you&#8217;ll notice we just introduced event handling. Event handlers in PowerBoots are specified in much the same way that Properties are.  Their parameter names always start with &#8220;On_&#8221; and they take a script block.  The Hyperlink element in a <span class="caps">WPF</span> window doesn&#8217;t automatically open a browser (because you can use it to change &#8220;pages&#8221; in a <span class="caps">WPF</span> application), so to make simple web links work, you have to handle the &#8220;RequestNavigate&#8221; event as shown above.</p>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots8.png" class="float-right-block" alt="" width="202" height="76" /></p>

	<p>In order to update your user interface when an event triggers, you&#8217;ll need to have a variable that points at the control(s) you want to affect.  You get a <code>$this</code> variable for free which points at the object that caused the event (eg: the Hyperlink in our previous example), but otherwise you need to handle this yourself. You can do that one of two ways: you can set a variable the way you normally would, and then use the variable in the form, or you can specify the variable name using the <code>-OutVariable</code> parameter.  Personally I prefer the latter, as it messes up the flow of code less, but it has the downside that the output variable is always an array, even when there&#8217;s only one item.</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$global</span>:Count <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><br />
&nbsp; &nbsp;WrapPanel &nbsp;$<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #009900;">&quot;Push Me&quot;</span> <span style="color: #000066;">-On_Click</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$global</span>:Count<span style="color: #66cc66;">++</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$label</span>.<span style="color: #003366;">Content</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;You clicked the button ${global:Count} times!&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$script</span>:label <span style="color: #66cc66;">=</span> Label <span style="color: #009900;">&quot;Nothing pushed so far&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$label</span> <span style="color: #666666; font-style: italic;"># You have to actually write-output the label</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#125;</span> <span style="color: #000066;">-Title</span> <span style="color: #009900;">&quot;Test App&quot;</span> <span style="color: #000066;">-On_Closing</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$global</span>:BootsOutput <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$global</span>:Count; <span style="color: #660033;">rm</span> variable:Count <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>I&#8217;ve made these examples slightly more complicated than they had to be to demonstrate some best practices.  When the Window is closed, the Out-Boots function returns the $BootsOutput variable &#8212; so if you want to <strong>output</strong> something from your gui, you need to set that variable.  You can, of course, access global scope variables using the scope prefix <code>$global:variableName</code>, so you can set many different variables which you read later in your script.  The catch is, sometimes the variables <em>have</em> to be explicitly set to script or even global scope in order to refer to the same variable in all of the event handlers&#8230;</p>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots9.png" class="float-right-block" alt="" width="260" height="84" /></p>

	<p>However, if you want to have this block of code actually <strong>output</strong> something into the pipeline, you&#8217;ll always want to use the <code>$BootsOutput</code> variable.  You can do that directly, the way the example above does, or you can simply use Write-Output! Inside the Out-Boots function, he Write-Output cmdlet just appends to the $BootsOutput variable &#8230; so it works pretty much exactly the way you would expect it to.</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;WrapPanel <span style="color: #000066;">-On_Load</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$Count</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span> <span style="color: #333;">&#125;</span> $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; Button <span style="color: #009900;">&quot;Push Me&quot;</span> <span style="color: #000066;">-On_Click</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Output</span></span> <span style="color: #333;">&#40;</span><span style="color: #66cc66;">++</span><span style="color: #660033; font-weight: bold;">$count</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># You have to use array notation ...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$block</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">Inlines</span>.<span style="color: #660033;">Clear</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span>; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$block</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">Inlines</span>.<span style="color: #003366;">Add</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;You clicked the button $count times!&quot;</span><span style="color: #333;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; TextBlock <span style="color: #009900;">&quot;Nothing pushed so far&quot;</span> <span style="color: #000066;">-OutVariable</span> script:block <span style="color: #000066;">-VerticalAlignment</span> Center<br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>The first example outputs <strong>just</strong> the count of how many times you clicked.  The second outputs a series of numbers from 1 to however many times you click.  It&#8217;s your choice of how to work with it.</p>

	<h3>We can have fun with colors</h3>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots10.png" class="float-right-block" alt="" width="318" height="286" /></p>

	<p>Boots gives you access to all the capabilities of the Windows Presentation Framework, but in some cases that comes at a cost, because we haven&#8217;t simplified their composability.  So we have RadialGradientBrush and LinearGradientBrush, but you have to specify the GradientStops etc &#8230;</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #000066;">-Background</span> <span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp;RadialGradientBrush $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; GradientStop <span style="color: #000066;">-Offset</span> <span style="color: #cc66cc;">0</span> <span style="color: #000066;">-Color</span> <span style="color: #009900;">&quot;#F00&quot;</span><br />
&nbsp; &nbsp; &nbsp; GradientStop <span style="color: #000066;">-Offset</span> <span style="color: #cc66cc;">1</span> <span style="color: #000066;">-Color</span> <span style="color: #009900;">&quot;#F90&quot;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;Label <span style="color: #009900;">&quot;Boots&quot;</span> <span style="color: #000066;">-HorizontalAlignment</span> Center `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">-VerticalAlignment</span> Center `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">-Foreground</span> White <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">80</span> `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">-FontWeight</span> Bold &nbsp;<span style="color: #000066;">-FontSize</span> <span style="color: #cc66cc;">40</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>We also have</p>

	<h3>So what does an InputBox look like?</h3>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots11.png" class="float-right-block" title="PowerBoots11.png" alt="PowerBoots11.png" width="260" height="86" /></p>

	<p>Well, the simplest possible input box is just a TextBox, with the Width set (if you don&#8217;t set the Width, a TextBox will adjust to fit it&#8217;s contents, which can be really distracting).  All you need to do is this:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;TextBox <span style="color: #000066;">-Width</span> <span style="color: #cc66cc;">220</span> <br />
<span style="color: #333;">&#125;</span> <span style="color: #000066;">-Title</span> <span style="color: #009900;">&quot;Enter your name&quot;</span> <span style="color: #000066;">-On_Close</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Output</span></span> <span style="color: #660033; font-weight: bold;">$BootsWindow</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">Text</span> <br />
<span style="color: #333;">&#125;</span> <br />
&nbsp;</div>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots12.png" class="float-right-block" title="PowerBoots12.png" alt="PowerBoots12.png" width="200" height="76" /></p>

	<p>Of course, the problem with that is that it pops up this rather confusing window, when what we really wanted was a prompt, and an &#8220;Ok&#8221; button, and some event handling to make the thing behave the way we expect it to.  So lets try our first complicated form. </p>

	<p>I&#8217;ll warn you ahead of time of one thing I&#8217;m going to do here. I&#8217;m using the &#8220;Border&#8221; element to apply a colored border to the StackPanel (because it doesn&#8217;t have it&#8217;s own border parameters), but then I&#8217;m also using the WindowStyle and AllowsTransparency properties to remove the normal window chrome, creating the bare little popup you see in the screenshot. I handle the mouse down event on the main window to allow the user to drag the window around by clicking anywhere on it (except in the TextBox or on the Button, of course). Now it looks slick, and &#8212;you know&#8212; it works!</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">BootsInput</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">Param</span><span style="color: #333;">&#40;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Prompt</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;Please enter your name:&quot;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Remove-<span style="font-style: normal;">Variable</span></span> textBox <span style="color: #000066;">-ErrorAction</span> SilentlyContinue<br />
&nbsp; &nbsp;Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; Border <span style="color: #000066;">-BorderThickness</span> <span style="color: #cc66cc;">4</span> <span style="color: #000066;">-BorderBrush</span> <span style="color: #009900;">&quot;#BE8&quot;</span> <span style="color: #000066;">-Background</span> <span style="color: #009900;">&quot;#EFC&quot;</span> <span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;StackPanel <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">10</span> &nbsp;$<span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Label <span style="color: #660033; font-weight: bold;">$Prompt</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StackPanel <span style="color: #000066;">-Orientation</span> Horizontal $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TextBox <span style="color: #000066;">-OutVariable</span> global:textbox <span style="color: #000066;">-Width</span> <span style="color: #cc66cc;">150</span> <span style="color: #000066;">-On_KeyDown</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Key</span> <span style="color: #000066;">-eq</span> <span style="color: #009900;">&quot;Return&quot;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Output</span></span> <span style="color: #660033; font-weight: bold;">$textbox</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">Text</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$BootsWindow</span>.<span style="color: #003366;">Close</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Button <span style="color: #009900;">&quot;Ok&quot;</span> <span style="color: #000066;">-On_Click</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Output</span></span> <span style="color: #660033; font-weight: bold;">$textbox</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">Text</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$BootsWindow</span>.<span style="color: #003366;">Close</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span> <span style="color: #000066;">-On_Load</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$textbox</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">Focus</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span> `<br />
&nbsp; &nbsp;<span style="color: #000066;">-WindowStyle</span> None <span style="color: #000066;">-AllowsTransparency</span> <span style="color: #660033; font-weight: bold;">$true</span> `<br />
&nbsp; &nbsp;<span style="color: #000066;">-On_PreviewMouseLeftButtonDown</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Source</span> <span style="color: #000066;">-notmatch</span> <span style="color: #009900;">&quot;.*\.(TextBox|Button)&quot;</span><span style="color: #333;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$BootsWindow</span>.<span style="color: #003366;">DragMove</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>Hopefully you can follow that, although it&#8217;s obviously over the top  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=':)' class='wp-smiley' /> . We handle the KeyDown event on the TextBox (if the Key is the Return key), and we also handle the click on the Button.  In both cases, we&#8217;ll write out the text that was entered, and use the special $BootsWindow variable to close the window.  We also handle the Load event for the window, to make sure the focus is on the TextBox, so you can just start typing.</p>

	<h3>A final example</h3>

	<p><img src="http://huddledmasses.org/images/PowerBoots/PowerBoots13.png" class="float-right-block" title="PowerBoots13.png" alt="PowerBoots13.png" width="248" height="740" /></p>

	<p>I&#8217;ve got quite a few more examples I want to show off in part two of this tutorial, but to get you thinking about ways to integrate this with your routine tasks, and give you some ideas of what you can do with what you know already, let me give you this example of browsing photos, with a visual indication of how big the image file is. Of course, the point is that you could be visualizing, you know &#8230; anything.</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #0066cc; font-style: italic;">add-<span style="font-style: normal;">type</span></span> <span style="color: #000066;">-Assembly</span> System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Forms</span> &nbsp;<span style="color: #666666; font-style: italic;"># To get the Double-Click time</span><br />
<br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">GraphLabel</span></span> <span style="color: #333;">&#123;</span><br />
<span style="color: #333;">&#91;</span>CmdletBinding<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">PARAM</span> <span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>Position<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">String</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Label</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;Name&quot;</span>, <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>Position<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">1</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">String</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Value</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;Length&quot;</span>, <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>Position<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">2</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">ScriptBlock</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$DoubleClickAction</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$null</span>, <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Int</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$max</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$null</span>, <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Int</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$width</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">200</span>, <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">double</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$margin</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Int</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$DoubleClickTime</span> <span style="color: #66cc66;">=</span> $<span style="color: #333;">&#40;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Forms</span>.<span style="color: #003366;">SystemInformation</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">DoubleClickTime</span><span style="color: #333;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>ValueFromPipeline<span style="color: #66cc66;">=</span><span style="color: #660033; font-weight: bold;">$true</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#91;</span>Alias<span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;IO&quot;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">PSObject</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$InputObject</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">BEGIN</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$maxx</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$max</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">PROCESS</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">!</span><span style="color: #660033; font-weight: bold;">$maxx</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$maxx</span><span style="color: #66cc66;">=</span>@<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$InputObject</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #660033; font-weight: bold;">$Value</span> <span style="color: #333;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">foreach</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$io</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #660033; font-weight: bold;">$InputObject</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## This is the core part of the script ...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## For each input, generate a grid panel with a label and a rectangle in the background</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GridPanel <span style="color: #000066;">-tag</span> @<span style="color: #333;">&#123;</span>item<span style="color: #66cc66;">=</span><span style="color: #660033; font-weight: bold;">$io</span>; action<span style="color: #66cc66;">=</span><span style="color: #660033; font-weight: bold;">$DoubleClickAction</span><span style="color: #333;">&#125;</span> <span style="color: #000066;">-width</span> <span style="color: #660033; font-weight: bold;">$Width</span> <span style="color: #000066;">-margin</span> <span style="color: #660033; font-weight: bold;">$margin</span> $<span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Label <span style="color: #660033; font-weight: bold;">$io</span>.<span style="color: #660033; font-weight: bold;">$Label</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Rectangle <span style="color: #000066;">-HorizontalAlignment</span> Left <span style="color: #000066;">-Fill</span> <span style="color: #009900;">&quot;#9F00&quot;</span> `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">-Width</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Width</span> <span style="color: #66cc66;">*</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$io</span>.<span style="color: #009900;">&quot;$Value&quot;</span> <span style="color: #66cc66;">/</span> <span style="color: #660033; font-weight: bold;">$maxx</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#41;</span> <span style="color: #000066;">-On_MouseLeftButtonDown</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$this</span>.<span style="color: #003366;">Tag</span>.<span style="color: #003366;">Action</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span> <span style="color: #666666; font-style: italic;"># They passed in a doubleclick action, so lets handle it</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$global</span>:ClickTime <span style="color: #000066;">-and</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#40;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>DateTime<span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">Now</span> <span style="color: #66cc66;">-</span> <span style="color: #660033; font-weight: bold;">$ClickTime</span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">TotalMilliseconds</span> <span style="color: #000066;">-lt</span> <span style="color: #660033; font-weight: bold;">$global</span>:DoubleClickTime<span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># We invoke the scriptblock </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># and pass it the original input object </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># and the grid panel object</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&amp;</span><span style="color: #660033; font-weight: bold;">$This</span>.<span style="color: #003366;">Tag</span>.<span style="color: #003366;">Action</span> <span style="color: #660033; font-weight: bold;">$this</span>.<span style="color: #003366;">Tag</span>.<span style="color: #003366;">Item</span> <span style="color: #660033; font-weight: bold;">$this</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$global</span>:ClickTime <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>DateTime<span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">Now</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Alias</span></span> GraphLabel <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">GraphLabel</span></span><br />
<br />
<span style="color: #666666; font-style: italic;">## Example 1: list of processes with most RAM usage</span><br />
<span style="color: #666666; font-style: italic;">## DoubleClickAction is `kill`</span><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #660033;">ps</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">sort</span> PM <span style="color: #000066;">-Desc</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Select</span> <span style="color: #000066;">-First</span> <span style="color: #cc66cc;">20</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp; &nbsp; GraphLabel ProcessName PM <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033;">Kill</span> <span style="color: #660033; font-weight: bold;">$Args</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">Id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$global</span>:panel<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">Children</span>.<span style="color: #003366;">Remove</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Args</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp;StackPanel <span style="color: #000066;">-ov</span> global:panel<br />
<span style="color: #333;">&#125;</span><br />
<span style="color: #666666; font-style: italic;">## Example 2: list of images, with file size indicated</span><br />
<span style="color: #666666; font-style: italic;">## DoubleClickAction is `open`</span><br />
Boots <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #660033;">ls</span> ~<span style="color: #66cc66;">/</span>Pictures<span style="color: #66cc66;">/</span> <span style="color: #000066;">-recurse</span> <span style="color: #000066;">-Include</span> <span style="color: #66cc66;">*</span>.<span style="color: #003366;">jpg</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Sort</span> Length <span style="color: #000066;">-Desc</span> <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">%</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">!</span><span style="color: #660033; font-weight: bold;">$Max</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$Max</span><span style="color: #66cc66;">=</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Length</span><span style="color: #333;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; StackPanel <span style="color: #000066;">-Width</span> <span style="color: #cc66cc;">200</span> <span style="color: #000066;">-Margin</span> <span style="color: #cc66cc;">5</span> $<span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Image <span style="color: #000066;">-Source</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">FullName</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GraphLabel Name Length <span style="color: #000066;">-Max</span> <span style="color: #660033; font-weight: bold;">$Max</span> <span style="color: #000066;">-IO</span> <span style="color: #660033; font-weight: bold;">$_</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Diagnostics.<span style="color: #666699; font-weight: bold;">Process</span><span style="color: #333;">&#93;</span></span>::<span style="color: #660033;">Start</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$args</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">FullName</span> <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#41;</span> <br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> WrapPanel <br />
<span style="color: #333;">&#125;</span> <span style="color: #000066;">-Width</span> <span style="color: #cc66cc;">800</span><br />
&nbsp;</div>

	<p>Notice that I had to manually handle the concept of a double click, because StackPanels don&#8217;t have a Click or DoubleClick event, just MouseDown and MouseUp.  I could have stuck the stackpanel into something that does, but there&#8217;s really no need.  Also, the <code>[Diagnostics.Process]::Start</code> is the equivalent of typing the name into the run dialog.  I&#8217;m just <em>executing</em> the jpg, which makes it open in the default editor.  It&#8217;s just a sample, after all.</p>

	<h3>End note</h3>

	<p>The current version of Boots does not add threading support, which means that when you run something through Boots, execution of your script stops until the window is closed.  You can get around this somewhat in <a href="http://huddledmasses.org/wpf-from-powershell-updating-windows/">various different ways</a>, but future releases <em>will</em> support running the <span class="caps">WPF</span> window in a separate thread, and even communicating to it &#8230; at the expense of a slightly different syntax. If you need that functionality, feel free to let me know &#8230; I could use some motivation.</p>

	<p>I hope you&#8217;ve enjoyed this tour through PowerBoots, and will be able to start applying it for fun and profit.</p>]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/powerboots-tutorial-walkthrough/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>More PowerBoots: PowerShell and Out-WPF</title>
		<link>http://joelbennett.net/more-powerboots-powershell-and-out-wpf/</link>
		<comments>http://joelbennett.net/more-powerboots-powershell-and-out-wpf/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 20:20:08 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[PowerBoots]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Shoes]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=952</guid>
		<description><![CDATA[I&#8217;m almost ready to release a version of Out-WPF which will work on both my PoshConsole host (embedding in the host when appropriate) and on PowerShell.exe, both in CTP3 and in v1 &#8230; but since Jeffrey outed my little video demo, I figured I might as well share it here. Please excuse the size of [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;m almost ready to release a version of Out-<span class="caps">WPF</span> which will work on both my PoshConsole host (embedding in the host when appropriate) and on PowerShell.exe, both in CTP3 and in v1 &#8230; but since <a href="http://blogs.msdn.com/powershell/archive/2009/01/05/checkout-out-wpf.aspx">Jeffrey outed my little video demo</a>, I figured I might as well share it here.  <span id="more-952"></span></p>

	<p>Please excuse the size of this thing &#8230; I&#8217;ll try to be less ridiculous next time, but in the meantime, you can <a href="http://www.screencast.com/t/2p1vO31i">view the full video at screencast.com</a>.</p>

	<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="830" height="480"> <param name="movie" value="http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/bootstrap.swf"></param> <param name="quality" value="high"></param> <param name="bgcolor" value="#FFFFFF"></param> <param name="flashVars" value="thumb=http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/FirstFrame.jpg&#038;width=830&#038;height=480&#038;content=http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/Out-WPF-ls1.swf"></param> <param name="allowFullScreen" value="true"></param> <param name="scale" value="showall"></param> <param name="allowScriptAccess" value="always"></param> <param name="base" value="http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/"></param>  <embed src="http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/bootstrap.swf" quality="high" bgcolor="#FFFFFF" width="620" height="358" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/FirstFrame.jpg&#038;width=830&#038;height=480&#038;content=http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/Out-WPF-ls1.swf" allowFullScreen="true" base="http://content.screencast.com/users/Jaykul/folders/Jing/media/38f69692-8d5b-48b8-9d72-5807dc03e62e/" scale="showall"></embed> </object></p>

	<p>P.S.  <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  I&#8217;ve released <a href="http://huddledmasses.org/powerboots/">PowerBoots</a> which does not quite do what you see in that demo (and only works with PowerShell 2.0 (currently at CTP3 release)), but <strong>can</strong> do all sorts of amazing things, as you can see in the <a href="http://huddledmasses.org/powerboots-tutorial-walkthrough/">PowerBoots tutorial</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/more-powerboots-powershell-and-out-wpf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PowerBoots &#8211; Shoes for PowerShell</title>
		<link>http://joelbennett.net/powerboots-shoes-for-powershell/</link>
		<comments>http://joelbennett.net/powerboots-shoes-for-powershell/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 06:09:44 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[PowerBoots]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Shoes]]></category>
		<category><![CDATA[Toolkit]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=911</guid>
		<description><![CDATA[If you haven&#8217;t seen the Ruby Shoes graphical framework, you should check it out. In fact, go read the tutorial and come back, because the rest of this will make a lot more sense then. It&#8217;s a very slick toolkit, right? Not only that, but it works on Windows, Linux, and Mac OS X &#8230; [...]]]></description>
			<content:encoded><![CDATA[	<p>If you haven&#8217;t seen the Ruby <a href="http://shoooes.net/">Shoes</a> graphical framework, you should check it out.  In fact, go read <a href="http://shoooes.net/tutorial/">the tutorial</a> and come back, because the rest of this will make a lot more sense then.</p>

	<p>It&#8217;s a <a href="http://shoooes.net/about/">very slick toolkit</a>, right? Not only that, but it works on Windows, Linux, and Mac OS X &#8230; unlike what I&#8217;m about to show you, which works only where PowerShell works &#8230;</p>

	<p>So, I&#8217;m curious if anyone would like something like that for PowerShell &#8230; and more to the point, how many people would be interested in it, and whether anyone would be willing to help write it (because exposing <strong>all</strong> of the properties of the various controls is going to require a lot of repetitive coding).  </p>

	<h3>What would it look like in PowerShell?</h3>

<div id="attachment_914" class="wp-caption alignright" style="width: 316px"><a href="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/powerboots1.png"><img src="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/powerboots1.png" alt="The simplest PowerBoots app" title="powerboots1" width="306" height="166" class="size-full wp-image-914" /></a><p class="wp-caption-text">The simplest PowerBoots app</p></div>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;"># These lines are the same (#2 uses aliases)</span><br />
<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Button</span></span> <span style="color: #009900;">&quot;Push Me&quot;</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Out-<span style="font-style: normal;">WPF</span></span><br />
button <span style="color: #009900;">&quot;Push Me&quot;</span> <span style="color: #66cc66;">|</span> Wpf</div>

<div id="attachment_916" class="wp-caption alignright" style="width: 310px"><a href="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/powerboots2.png"><img src="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/powerboots2-300x85.png" alt="A few more buttons, in a stack" title="powerboots2" width="300" height="85" class="size-medium wp-image-916" /></a><p class="wp-caption-text">A few more buttons, in a stack</p></div>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;"># Again, these lines are the same (#2 uses aliases)</span><br />
<span style="color: #009900;">&quot;A bed of clams&quot;</span>, <span style="color: #009900;">&quot;A coalition of cheetahs&quot;</span>, <span style="color: #009900;">&quot;A gulp of swallows&quot;</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Button</span></span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Stack</span></span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Out-<span style="font-style: normal;">Wpf</span></span><br />
<span style="color: #009900;">&quot;A bed of clams&quot;</span>, <span style="color: #009900;">&quot;A coalition of cheetahs&quot;</span>, <span style="color: #009900;">&quot;A gulp of swallows&quot;</span> <span style="color: #66cc66;">|</span> Button <span style="color: #66cc66;">|</span> Stack <span style="color: #66cc66;">|</span> Wpf</div>

	<p>As a disclaimer, I copied the examples here from <a href="http://shoooes.net/tutorial/">the Shoes tutorial</a> I mentioned earlier, which is why they&#8217;re slightly kooky (<a href="http://whytheluckystiff.net/">Why The Lucky Stiff</a> is a strange guy), and why I suggested you go read it before you read this. Of course, although these demos do work &#8212;and it&#8217;s all skinable and themeable&#8212; this is practically all that works in my demo, so don&#8217;t go thinking I&#8217;ve got a whole Shoes implementation for PowerShell.</p>

<div id="attachment_918" class="wp-caption alignright" style="width: 310px"><a href="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/powerboots3.png"><img src="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/powerboots3-300x66.png" alt="A few options" title="powerboots3" width="300" height="66" class="size-medium wp-image-918" /></a><p class="wp-caption-text">A few options</p></div>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #009900;">&quot;A bed of clams&quot;</span>, <span style="color: #009900;">&quot;A coalition of cheetahs&quot;</span>, <span style="color: #009900;">&quot;A gulp of swallows&quot;</span> <span style="color: #66cc66;">|</span> Button <span style="color: #000066;">-margin</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">|</span> Stack <span style="color: #000066;">-margin</span> <span style="color: #cc66cc;">8</span> <span style="color: #000066;">-background</span> red <span style="color: #66cc66;">|</span> Wpf</div>

	<p>I&#8217;m just trying to gauge the interest level &#8212; so if you&#8217;re interested, please comment below and let me know that you want it, what sorts of things you want it for (if you can think of any off the top of your head), and/or how involved you&#8217;d like to be.  I&#8217;d love for someone to say: &#8220;Wow, that&#8217;s a great idea, I&#8217;m going to go finish it&#8221;, but anything short of that, right down to &#8220;I&#8217;d give you $5 to write it and give it away&#8221; is acceptable  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=';)' class='wp-smiley' /> </p>

	<p>One final note: the Out-Wpf cmdlet that you see here <strong>does</strong> work in v1 and v2 and can even do this (click for the full picture):</p>

<div id="attachment_917" class="wp-caption alignright" style="width: 310px"><a href="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/out-wpf-v1.png"><img src="http://huddledmasses.org/wordpress/wp-content/uploads/2008/12/out-wpf-v1-300x135.png" alt="Out-WPF without PoshConsole" title="out-wpf-v1" width="300" height="135" class="size-medium wp-image-917" /></a><p class="wp-caption-text">Out-WPF without PoshConsole</p></div>

	<p>I&#8217;ll release <strong>that</strong> later this week&#8230;</p>

	<h4> <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  <a href="http://huddledmasses.org/powerboots/">PowerBoots Release</a></h4>

	<p>I&#8217;ve released a full script-based version of this. While it does everything you see above and more, it does <strong>not</strong> work in PowerShell 1. You can get an idea of how to use it by following the <a href="http://huddledmasses.org/powerboots-tutorial-walkthrough/">PowerBoots tutorial</a>, and you can <a href="http://huddledmasses.org/powerboots/">download PowerBoots</a>, but for now it requires v2 CTP3.  Let me hear from you if v1 support is important to ya.</p>]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/powerboots-shoes-for-powershell/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>WPF Window &#8220;Native&#8221; Behavior: Snap-To Screen Edges</title>
		<link>http://joelbennett.net/wpf-windows-that-snap-to-screen-edges/</link>
		<comments>http://joelbennett.net/wpf-windows-that-snap-to-screen-edges/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 05:06:36 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[NativeBehaviors]]></category>
		<category><![CDATA[Win32]]></category>
		<category><![CDATA[WM_WINDOWPOSCHANGING]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=718</guid>
		<description><![CDATA[There are many desirable behaviors for Windows applications that are just much harder to do than they should be with the tools that Microsoft has provided in the .Net Framework. In WPF, many of these behaviors are even harder to create than in Windows Forms because the necessary hooks take a bit more work to [...]]]></description>
			<content:encoded><![CDATA[	<p>There are many desirable behaviors for Windows applications that are just much harder to do than they should be with the tools that Microsoft has provided in the .Net Framework. In <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation" title="Windows Presentation Foundation" rel="wikipedia" class="zem_slink">WPF</a>, many of these behaviors are even harder to create than in <a href="http://en.wikipedia.org/wiki/Windows_Forms" title="Windows Forms" rel="wikipedia" class="zem_slink">Windows Forms</a> because the necessary hooks take a bit more work to write (thanks to the fact that there&#8217;s no window handles, so dropping down to &#8220;Native&#8221; code is harder.  Luckily, <span class="caps">WPF</span> Attached Properties give us a whole new way to reuse these behaviors once they&#8217;re written.</p>

	<p>I&#8217;ve started working on a few classes I&#8217;m calling NativeBehaviors, because they rely on intercepting the native <em>Window Message</em> processing, and I&#8217;ve put together a simple framework to let me write them, which I thought I would share.  The first one I wrote is a SnapToBehavior, which implements a feature that people seem to be constantly re-implementing in apps. Basically, it makes a window snap to the screen edge when it gets close (and prevents them from being moved off-screen).  I&#8217;ve also written a Global HotkeysBehavior which lets you register Hotkeys that work whenever your app is running (even if another app is active) so you can create a Hotkey to hide your app and show it, or whatever.</p>

	<p>In the rest of this article I&#8217;ll show you how to achieve this in <span class="caps">WPF</span> using my base NativeBehavior class, and how to use it on a Window. Since some of you won&#8217;t really care how it works, let&#8217;s start with:</p>

	<h3>How to make your <span class="caps">WPF</span> Windows snap to screen edges in 3 easy steps:</h3>

	<p>Step 1. Add a reference to the Huddled.Wpf.Interop library.<br />
Step 2. Add my Xml namespace to your root Window element<br />
Step 3. Paste three lines from below&#8230;.</p>

	<div class="xml code xml" style="font-family:monospace;"><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Window</span> <span style="color: #000066;">x:Class</span>=<span style="color: #ff0000;">&quot;GlobalHotkeys.DemoWindow&quot;</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;DemoWindow&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">Title</span>=<span style="color: #ff0000;">&quot;GlobalHotkeys&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;300&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;300&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:x</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:huddled</span>=<span style="color: #ff0000;">&quot;http://schemas.huddledmasses.org/wpf&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #808080; font-style: italic;">&lt;!-- You just add a reference to the library, add the &quot;huddled&quot; namespace, and paste: --&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:SnapToBehavior</span> <span style="color: #000066;">SnapDistance</span>=<span style="color: #ff0000;">&quot;20&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #808080; font-style: italic;">&lt;!-- The rest of your window can be whatever you like. --&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Label</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;Drag this window near the screen edges&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Window<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp;</div>

	<p>I should point out the &#8220;SnapDistance&#8221; property of the SnapToBehavior is actually a <span class="caps">WPF</span> &#8220;Thickness&#8221; which lets you specify the distance from the screen edge as a single number to use on all sides, or as a separate number for each side: Left, Top, Right, Bottom. And that&#8217;s pretty much all there is to know.</p>

	<h3>How to implement a NativeBehavior.</h3>

	<p>The implementation of the SnapToBehavior is actually ridiculously simple, given the NativeBehavior framework.  I simply created a SnapToBehavior class which derives from NativeBehavior, and implemented the single mandatory method:</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span><br />
<span style="color: #008080; font-style: italic;">/// Gets the MessageMappings for this behavior:</span><br />
<span style="color: #008080; font-style: italic;">/// A single mapping of a handler for WM_WINDOWPOSCHANGING.</span><br />
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
<span style="color: #008080; font-style: italic;">/// &lt;returns&gt;An enumerable collection of MessageMapping objects.&lt;/returns&gt;</span><br />
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">override</span> IEnumerable<span style="color: #008000;">&lt;</span>MessageMapping<span style="color: #008000;">&gt;</span> GetHandlers<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;yield <span style="color: #0600FF;">return</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> MessageMapping<span style="color: #000000;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; NativeMethods.<span style="color: #0000FF;">WindowMessage</span>.<span style="color: #0000FF;">WindowPositionChanging</span>, <span style="color: #008080; font-style: italic;">// the message</span><br />
&nbsp; &nbsp; &nbsp; OnPreviewPositionChange<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// the delegate which will handle that message</span><br />
<span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<p>When my new behavior is added to the Behaviors collection, my handler will be registered, and whenever the WM_WINDOWPOSCHANGING message arrives, it will be called.  Now I defined a <a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx">DependencyProperty</a> for the SnapDistance, so that you could set that in <span class="caps">XAML</span>.  It&#8217;s extremely simple, and VisualStudio has a built-in snippet for dependency properties, but here&#8217;s the code:</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">readonly</span> DependencyProperty SnapDistanceProperty <span style="color: #008000;">=</span><br />
&nbsp; &nbsp;DependencyProperty.<span style="color: #0000FF;">Register</span><span style="color: #000000;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666;">&quot;SnapDistance&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// The name of the property (must match)</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>Thickness<span style="color: #000000;">&#41;</span>, &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// The type of the values</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>SnapToBehavior<span style="color: #000000;">&#41;</span>, &nbsp; <span style="color: #008080; font-style: italic;">// The type this property shows up on</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> UIPropertyMetadata<span style="color: #000000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Thickness<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">20</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #008080; font-style: italic;">// The default value</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #0600FF;">public</span> Thickness SnapDistance<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> <span style="color: #000000;">&#40;</span>Thickness<span style="color: #000000;">&#41;</span>GetValue<span style="color: #000000;">&#40;</span>SnapDistanceProperty<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;set <span style="color: #000000;">&#123;</span> SetValue<span style="color: #000000;">&#40;</span>SnapDistanceProperty, value<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<p>Once I have that, the last piece of the puzzle is to actually handle the window position changing message (think of it as an event, if you&#8217;re not used to Win32 message-based programming).</p>

	<p>The basics of handling WM_WINDOWPOSCHANGING is that you get a structure passed in which has the <strong>proposed</strong> position of the Window, (including it&#8217;s z-index related to other apps) and you can basically tweak that however you like.  Obviously there are lots of possibilities for this single message: always-on-bottom windows, undraggable windows, etc., but in our case we&#8217;re just concerned about how close we are to the edge.</p>

	<p>We use the SystemParameters class to get the VirtualScreenLeft, VirtualScreenTop, and VirtualScreenWidth and VirtualScreenHeight which define the rectangle we&#8217;ll use for snapping.  In the case of non-rectangular arrangements of multiple monitors this isn&#8217;t quite sufficient, but for our example anything more would be a distraction.  Then we just check to see if the proposed position is within the &#8220;SnapDistance&#8221; of any of the edges, and if so, we change the position to be against the edge.  That&#8217;s really all there is to it.</p>

	<p>If you look at the code example below you&#8217;ll see I have to &#8220;Marshal&#8221; the WindowPosition structure in and out of an IntPtr which is passed in the WindowMessage &#8230; that&#8217;s the downside of intercepting window messages that the framework doesn&#8217;t already translate for us, but in this particular case, it&#8217;s actually fairly trivial.</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;lParam for WindowPositionChanging</span><br />
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
<span style="color: #000000;">&#91;</span>StructLayout<span style="color: #000000;">&#40;</span>LayoutKind.<span style="color: #0000FF;">Sequential</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span><br />
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">struct</span> WindowPosition<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> IntPtr Handle<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> IntPtr HandleInsertAfter<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Left<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Top<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Width<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Height<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> WindowPositionFlags Flags<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Right <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> Left <span style="color: #008000;">+</span> Width<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Bottom <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> Top <span style="color: #008000;">+</span> Height<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span> &nbsp; <br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">private</span> IntPtr OnPreviewPositionChange<span style="color: #000000;">&#40;</span>IntPtr wParam, IntPtr lParam, <span style="color: #0600FF;">ref</span> <span style="color: #FF0000;">bool</span> handled<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #FF0000;">bool</span> updated <span style="color: #008000;">=</span> false<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var windowPosition <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>NativeMethods.<span style="color: #0000FF;">WindowPosition</span><span style="color: #000000;">&#41;</span>Marshal.<span style="color: #0000FF;">PtrToStructure</span><span style="color: #000000;">&#40;</span>lParam, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>NativeMethods.<span style="color: #0000FF;">WindowPosition</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Flags</span> <span style="color: #008000;">&amp;</span> NativeMethods.<span style="color: #0000FF;">WindowPositionFlags</span>.<span style="color: #0000FF;">NoMove</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// If we use the WPF SystemParameters, these should be &quot;Logical&quot; pixels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Rect validArea <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Rect<span style="color: #000000;">&#40;</span>SystemParameters.<span style="color: #0000FF;">VirtualScreenLeft</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemParameters.<span style="color: #0000FF;">VirtualScreenTop</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemParameters.<span style="color: #0000FF;">VirtualScreenWidth</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemParameters.<span style="color: #0000FF;">VirtualScreenHeight</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Rect snapToBorder <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Rect<span style="color: #000000;">&#40;</span>SystemParameters.<span style="color: #0000FF;">VirtualScreenLeft</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Left</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemParameters.<span style="color: #0000FF;">VirtualScreenTop</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Top</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemParameters.<span style="color: #0000FF;">VirtualScreenWidth</span> <span style="color: #008000;">-</span> <span style="color: #000000;">&#40;</span>SnapDistance.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Right</span><span style="color: #000000;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemParameters.<span style="color: #0000FF;">VirtualScreenHeight</span> <span style="color: #008000;">-</span> <span style="color: #000000;">&#40;</span>SnapDistance.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Bottom</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce left boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">&lt;</span> snapToBorder.<span style="color: #0000FF;">Left</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>validArea.<span style="color: #0000FF;">Left</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce top boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">&lt;</span> snapToBorder.<span style="color: #0000FF;">Y</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>validArea.<span style="color: #0000FF;">Top</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce right boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Right</span> <span style="color: #008000;">&gt;</span> snapToBorder.<span style="color: #0000FF;">Right</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#40;</span>validArea.<span style="color: #0000FF;">Right</span> <span style="color: #008000;">-</span> windowPosition.<span style="color: #0000FF;">Width</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce bottom boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Bottom</span> <span style="color: #008000;">&gt;</span> snapToBorder.<span style="color: #0000FF;">Bottom</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#40;</span>validArea.<span style="color: #0000FF;">Bottom</span> <span style="color: #008000;">-</span> windowPosition.<span style="color: #0000FF;">Height</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>updated<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Marshal.<span style="color: #0000FF;">StructureToPtr</span><span style="color: #000000;">&#40;</span>windowPosition, lParam, <span style="color: #0600FF;">true</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> IntPtr.<span style="color: #0000FF;">Zero</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<h3>Download it, or get the source code</h3>

	<p>If you&#8217;d like, you can download the current <a href='http://HuddledMasses.org/wordpress/wp-content/uploads/2008/10/huddledinteropwpf.dll'>Huddled Interop for <span class="caps">WPF</span> library</a> right now, or you can check out the source from CodePlex <a href="https://poshconsole.svn.codeplex.com/svn/trunk/Huddled/">SVN</a> or just download the <a href="http://www.codeplex.com/PoshConsole/SourceControl/ListDownloadableCommits.aspx">most recent commit</a> (You are only interested in the &#8220;Huddled&#8221; project which is in the &#8220;trunk&#8221;, not the &#8220;trunk-3.5&#8221;).  <span class="emph1">The source is licensed freely under the <span class="caps">BSD</span> or <span class="caps">GPL</span> v2</span> (and a few other licenses, see the top of the source code files).</p>

	<p>Either way you&#8217;ll get not just the SnapToBehavior but also the global HotkeysBehavior, and the Native Behaviors framework which I&#8217;ll write more about later, but for now, in case you want to try to use it, here&#8217;s an example using both the SnapTo and HotkeysBehavior (you can find this in the <a href="https://poshconsole.svn.codeplex.com/svn/trunk/GlobalHotkeys">GlobalHotkeys</a> demo project, which includes some sample code for handling hotkey conflicts).  Enjoy.</p>

	<div class="xml code xml" style="font-family:monospace;"><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Window</span> <span style="color: #000066;">x:Class</span>=<span style="color: #ff0000;">&quot;GlobalHotkeys.DemoWindow&quot;</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;window&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:x</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:huddled</span>=<span style="color: #ff0000;">&quot;http://schemas.huddledmasses.org/wpf&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">Title</span>=<span style="color: #ff0000;">&quot;Demo Window!&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;300&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:SnapToBehavior</span> <span style="color: #000066;">SnapDistance</span>=<span style="color: #ff0000;">&quot;80,20,80,10&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:HotkeysBehavior<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;KeyBinding</span> <span style="color: #000066;">Command</span>=<span style="color: #ff0000;">&quot;huddled:GlobalCommands.ActivateWindow&quot;</span> <span style="color: #000066;">Key</span>=<span style="color: #ff0000;">&quot;K&quot;</span> &nbsp;<span style="color: #000066;">Modifiers</span>=<span style="color: #ff0000;">&quot;Win&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;KeyBinding</span> <span style="color: #000066;">Command</span>=<span style="color: #ff0000;">&quot;huddled:GlobalCommands.CloseWindow&quot;</span> &nbsp; &nbsp;<span style="color: #000066;">Key</span>=<span style="color: #ff0000;">&quot;F4&quot;</span> <span style="color: #000066;">Modifiers</span>=<span style="color: #ff0000;">&quot;Win&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;KeyBinding</span> <span style="color: #000066;">Command</span>=<span style="color: #ff0000;">&quot;huddled:GlobalCommands.ToggleWindow&quot;</span> &nbsp; <span style="color: #000066;">Key</span>=<span style="color: #ff0000;">&quot;S&quot;</span> &nbsp;<span style="color: #000066;">Modifiers</span>=<span style="color: #ff0000;">&quot;Win&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/huddled:HotkeysBehavior<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Label</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;Drag this window near the screen edges&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Window<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/wpf-windows-that-snap-to-screen-edges/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF From PowerShell &#8211; Select-Grid</title>
		<link>http://joelbennett.net/wpf-from-powershell-select-grid/</link>
		<comments>http://joelbennett.net/wpf-from-powershell-select-grid/#comments</comments>
		<pubDate>Tue, 20 May 2008 21:09:30 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Forms]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=537</guid>
		<description><![CDATA[After looking over the scripts I&#8217;ve pasted in the last few days it struck me that all of them load the UI from XAML &#8212; and for the most part, you can do pretty much whatever you need to do in WPF in pure PowerShell if you want to. To demonstrate this, I wrote a [...]]]></description>
			<content:encoded><![CDATA[	<p>After looking over the scripts I&#8217;ve pasted in the last few days it struck me that all of them load the UI from <span class="caps">XAML</span> &#8212; and for the most part, you can do pretty much whatever you need to do in <span class="caps">WPF</span> in pure PowerShell if you want to.</p>

	<p><a href='http://HuddledMasses.org/wpf-from-powershell-select-grid/select-grid-screenshot/'><img src="http://HuddledMasses.org/wordpress/wp-content/uploads/2008/05/select-grid-screenshot-mini.png" alt="Select-Grid Screenshot" title="select-grid-screenshot-mini" class="alignleft wp-image-542" style="float: left;"/></a>To demonstrate this, I wrote a simple Out-Grid script.  But then I got carried away, and wrote the script I&#8217;ve shown in this screenshot.  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=':-D' class='wp-smiley' />   The resulting script not only illustrates how to code <span class="caps">WPF</span> in PowerShell without <span class="caps">XAML</span>, it also illustrates one of the few areas where you&#8217;re much better off loading from <span class="caps">XAML</span> than writing the plain code &#8212; and that&#8217;s a DataTemplate. It <strong>is</strong> possible to write them in code, but believe it or not, some of their features are accessible only from <span class="caps">XAML</span>.</p>

	<p> <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  I&#8217;ve updated both the script and the screenshot to correct a bug I noticed last night after I posted this &#8230; so if you tried this and got a lot more columns than you had bargained for &#8230; here is the <a href='http://HuddledMasses.org/?attachment_id=539' rel='attachment wp-att-539'>Select-Grid script</a> again.   <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  I updated it <em>again</em> just now to switch my <code>Set-PsDebug</code> statement for a <code>Set-StrictMode</code> statement, after reading Jeffrey Snover&#8217;s post about <a href="http://blogs.msdn.com/powershell/archive/2008/05/21/strict-mode.aspx">strict mode best practices</a>.</p>

	<p>I&#8217;m not going to paste the <em>whole</em> script in-line, but I thought I&#8217;d paste some of it here so that I could give a little explanation of what&#8217;s happening, in case you need a little help figuring it out&#8230;</p>

	<h3>Using modules &#8230;</h3>

	<p>Some of you may know that normally in a script like this we would put the &#8220;utility&#8221; functions inside the <code>BEGIN</code> block so-as to encapsulate them from your main runspace, and may be wondering why I didn&#8217;t in this case.  It&#8217;s because the new CTP2 of PowerShell has this concept called a &#8220;module&#8221; ... which is somewhat like a script snapin &#8212; basically it allows you to have functions in the script which don&#8217;t end up in the main runspace, but which are still available to the other functions (or cmdlets, in this case) in the script.  </p>

	<p>I will write a separate post about how <a href="/powershell-modules/">PowerShell Modules</a> work, and what you can do with them &#8230; it&#8217;s too complicated to get into here.  Suffice it to say that all I had to do to the script is add a line at the bottom: <code>Export-ModuleMember Select-Grid</code> and rename it to  <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  <a href='http://HuddledMasses.org/wpf-from-powershell-select-grid/select-grid-2/' rel='attachment wp-att-544'>Select-Grid.psm1</a> and put it in a specific location: Documents\WindowsPowerShell\Packages\Select-Grid\Select-Grid.psm1  &#8212; but of course, I couldn&#8217;t resist cleaning it up a bit as I was writing about it (if you grabbed it before v3.4, you should grab it again &#8212; look in the comment at the top).</p>

	<p>Having done that, all you have to do is run <code>Add-Module Select-Grid</code> instead of dot-sourcing it, and then run it as before (see <a href="http://HuddledMasses.org/wordpress/wp-content/uploads/2008/05/select-grid-screenshot.png">the screenshot</a>).</p>

	<h3>Let&#8217;s talk about <em>code</em> bay-bee &#8230;</h3>

	<p>There&#8217;s a few things I wanted to point out in the module&#8217;s code, so lets get to that.<span id="more-537"></span>  The first thing is that the main code is in a cmdlet, rather than a function &#8212; mostly because the cmdlet automatically handles both command arguments and pipeline arguments and allows me to handle them both the same way.  Since I want to handle all of the input at once, my <code>BEGIN</code> and <code>PROCESS</code> blocks are basically empty, serving only to collect the inputs.</p>

	<p>One caveat I will point out: The <span class="caps">CTP</span> has a problem where it strips the <acronym title="Extended Type System">ETS</acronym> attributes from things when you specify the type. So if you write a cmdlet with a parameter types like <code>[System.IO.FileSystemInfo]</code>, and then add data to them with Add-Member, that data won&#8217;t show up in the script cmdlet.  Hopefully this will be considered an <a href="https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=345387&#38;SiteID=99">important bug</a> and will be fixed in the next CTP/Beta.  The workaround in the meantime is to just use <code>[PSObject]</code> when you want to get the <span class="caps">ETS</span> attributes.</p>

	<p>So, lets review the important bits of this &#8230;</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$window</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Window</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">SizeToContent</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;WidthAndHeight&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">SnapsToDevicePixels</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$true</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Content</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Controls</span>.<span style="color: #003366;">ListView</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Title</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Title</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$Title</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Title</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$outputObjects</span><span style="color: #333;">&#91;</span><span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">GetType</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">Name</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">### The ListView takes ViewBase object which controls the layout and appearance</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">### We'll use a GridView</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">View</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Controls</span>.<span style="color: #003366;">GridView</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">View</span>.<span style="color: #003366;">AllowsColumnReorder</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$true</span></div>

	<p>This constructs the window, and the only things I&#8217;ll point out here is that I used SizeToContent so that the window would automatically adjust it&#8217;s size, and I put the ListView and GridView directly into their containers, instead of assigning them to variables first.  It might help you to have a <code>$grid</code> or a <code>$list</code> variable to work with in the rest of the code (eg: instead of <code>$window.Content.View = new...GridView</code>, you&#8217;d be doing <code>$list.View = $grid</code>), but since this is PowerShell and not C#, I don&#8217;t end up having to <em>manually</em> cast things to use their specific properties, so this actually keeps my code cleaner.  In C# this would be a mess, because the <code>View</code> property is only a property of a ListView type, so you would have to cast the <code>$Window.Content</code> to a ListView in order to use that property, and then &#8230; well, lets just say the last line of that code would end up something like this (assuming you were <strong>using</strong> the namespaces and didn&#8217;t have to type them out):</p>

	<div class="csharp code csharp" style="font-family:monospace;"><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>GridView<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>ListView<span style="color: #000000;">&#41;</span>window.<span style="color: #0000FF;">Content</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">View</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">AllowsColumnReorder</span> <span style="color: #008000;">=</span> <span style="color: #0600FF;">true</span></div>

	<p>The next interesting feature of this code (at least, in my opinion) is the <code>Get-PropertyTypes</code> function &#8212; I won&#8217;t elaborate much here, but the purpose of this code is to get a hash of the property <em>names</em> and <em>types</em> when the user specifies a list of properties to show.  The main reason I did this that I was having problems sorting columns with missing values, so I go through the values and add a NoteProperty with an appropriate default (for which I need to know the variable&#8217;s type).</p>

	<p>We then construct columns for each property we want to bind to.  This could be drastically simplified if we didn&#8217;t need the sorting, but since we do, it looks like this:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">foreach</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Name</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #660033; font-weight: bold;">$Properties</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## For each property, make a column &nbsp; &nbsp; &nbsp; &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$gvc</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Controls</span>.<span style="color: #003366;">GridViewColumn</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## And bind the data ... </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$gvc</span>.<span style="color: #003366;">DisplayMemberBinding</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366;">Windows</span>.<span style="color: #666699; font-weight: bold;">Data</span>.<span style="color: #003366;">Binding</span> <span style="color: #660033; font-weight: bold;">$Name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## In order to add sorting, we need to create the header ourselves</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$gvc</span>.<span style="color: #003366;">Header</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Controls</span>.<span style="color: #003366;">GridViewColumnHeader</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$gvc</span>.<span style="color: #003366;">Header</span>.<span style="color: #003366;">Content</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$Name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">##</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## Add a click handler to enable sorting ...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$gvc</span>.<span style="color: #003366;">Header</span>.<span style="color: #003366;">add_click</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$view</span> <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>System.<span style="color: #003366;">Windows</span>.<span style="color: #666699; font-weight: bold;">Data</span>.<span style="color: #003366;">CollectionViewSource</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">GetDefaultView</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$outputObjects</span> <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$view</span>.<span style="color: #003366;">SortDescriptions</span>.<span style="color: #660033;">Clear</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$view</span>.<span style="color: #003366;">SortDescriptions</span>.<span style="color: #003366;">Add</span><span style="color: #333;">&#40;</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">SortDescription</span></span> <span style="color: #660033; font-weight: bold;">$this</span>.<span style="color: #003366;">Content</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$view</span>.<span style="color: #003366;">Refresh</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span> <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## Use that column in the view</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">View</span>.<span style="color: #003366;">Columns</span>.<span style="color: #003366;">Add</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$gvc</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>That block only has one thing worth mentioning that might not be clear from the comments: to avoid double-sorting the data, we have to <code>Clear()</code> the SortDescriptions before we add a new one (otherwise it sorts when we add, and then sorts again when we remove the old SortDescription). Since we need to know the <em>direction</em> that the current sort is in, I refactored it into a module-level variable, and wrote a <code>New-SortDescription</code> function which creates the SortDescription based on that &#8230; allowing me to clear without first capturing the current sort direction, and then add the SortDescription straight to the GridView.  Script modules rock &#8212; they are essentially a &#8220;class&#8221; semantic for PowerShell, with private member variables and everything.</p>

	<p>The last thing I should write about is the CellTemplate magic.  If you pass a <code>Graph</code> parameter to the cmdlet, it puts a custom CellTemplate on each column you name. If you specified the <code>Properties</code> parameter, you have to be careful to only specify column names which you also included there, and in general, they have to be numeric columns in order for this to work.</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">foreach</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$obj</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #660033; font-weight: bold;">$outputObjects</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Member</span></span> NoteProperty <span style="color: #009900;">&quot;$($property)Percent&quot;</span> <span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#40;</span>$<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$obj</span>.$<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$property</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #000066;">-as</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">double</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">/</span> $<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$max</span>.<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$property</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #000066;">-input</span> <span style="color: #660033; font-weight: bold;">$obj</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$column</span> <span style="color: #66cc66;">=</span> @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$gridview</span>.<span style="color: #003366;">Columns</span> <span style="color: #66cc66;">|</span> ? <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Header</span>.<span style="color: #003366;">Content</span> <span style="color: #000066;">-eq</span> <span style="color: #660033; font-weight: bold;">$property</span> <span style="color: #333;">&#125;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">## dump the binding and use a template instead... (this shouldn't be necessary)...</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$column</span>.<span style="color: #003366;">DisplayMemberBinding</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$null</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$column</span>.<span style="color: #003366;">CellTemplate</span> <span style="color: #66cc66;">=</span> `<br />
&nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Windows.<span style="color: #003366;">Markup</span>.<span style="color: #003366;">XamlReader</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">Load</span><span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366; font-weight: bold;">Xml</span>.<span style="color: #003366;">XmlNodeReader</span> <span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Xml</span><span style="color: #333;">&#93;</span></span><span style="color: #009900;">&quot;&lt;DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Grid&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Rectangle Margin='-6,0' VerticalAlignment='Stretch' RenderTransformOrigin='0,1' &gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Rectangle.Fill&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;LinearGradientBrush StartPoint='0,0' EndPoint='1,0'&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;GradientStop Color='#FFFF4500' Offset='0' /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;GradientStop Color='#FFFF8585' Offset='1' /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/LinearGradientBrush&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/Rectangle.Fill&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Rectangle.RenderTransform&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;ScaleTransform ScaleX='{Binding $($property)Percent}' ScaleY='1' /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/Rectangle.RenderTransform&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/Rectangle&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;TextBlock Width='100' Margin='-6,0' TextAlignment='Right' Text='{Binding $property}' /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/Grid&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/DataTemplate&gt;&quot;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span></div>

	<p>There&#8217;s really only three lines of code here (not counting the Xaml), so lets review them. First we add a &#8220;PropertyPercent&#8221; NoteProperty to each output object for each &#8220;Property&#8221; that we want to graph, and populate it with the appropriate value.  Then, we find the appropriate column in the GridView that we&#8217;ve already set up &#8212; and remove it&#8217;s DisplayMemberBinding.  If we don&#8217;t remove the binding, the CellTemplate has no effect.</p>

	<p>Finally, we add the CellTemplate.  The magic is that the cell template has a colored <code>Rectangle</code> behind a <code>TextBlock</code>, and uses a <code>ScaleTransform</code> &#8212; bound to the &#8220;PropertyPercent&#8221; NoteProperty we created earlier &#8212; to scale the width of the Rectangle.  I can&#8217;t stress enough that this is just one of hundreds of possible visualizations you could use, so let me give you a few ideas, and then you should go find a friend that&#8217;s an artist or a designer and get them to spend some time playing with Expression Blend &#8230;</p>

	<ol>
		<li>You could have a DataTransform that converted numbers to colors, and bind the TextBlock&#8217;s <code>BackgroundBrush</code> to that so each cell is simply colored differently (eg: to color cells from red to blue based on a temperature value).</li>
		<li>You could databind the FontSize of a TextBlock based on a numeric value in a non-displayed property, so you could show words with relative size (like a &#8220;Tag Cloud&#8221;).</li>
	</ol>
	<ol>
		<li>You could databind the Angle property of the RotateTransform on a pair of lines or shapes to create an analog clock to display times</li>
	</ol>

	<p>So many possibilities &#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/wpf-from-powershell-select-grid/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WPF From PowerShell &#8211; Something Useful</title>
		<link>http://joelbennett.net/wpf-from-powershell-something-useful/</link>
		<comments>http://joelbennett.net/wpf-from-powershell-something-useful/#comments</comments>
		<pubDate>Wed, 14 May 2008 18:37:57 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Forms]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=530</guid>
		<description><![CDATA[After posting my last post, I started thinking that perhaps I shouldn&#8217;t really have started with something so splashy . So I started thinking about what I could use as a proper example &#8212; not of what WPF can do, but of what you might want to use WPF for in PowerShell. I came up [...]]]></description>
			<content:encoded><![CDATA[	<p>After posting <a href="/wpf-from-powershell-updating-windows/">my last post</a>, I started thinking that perhaps I shouldn&#8217;t really have started with something so splashy  <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[rolleyes]' class='wp-smiley' /> .  So I started thinking about what I could use as a proper example &#8212; not of what <span class="caps">WPF</span> can do, but of what you might want to use <span class="caps">WPF</span> for in PowerShell.</p>

	<p>I came up with two really obvious ideas which I think are both good demonstrations of useful things to do from PowerShell, and are good examples of something that really just doesn&#8217;t work with WinForms.</p>

	<h3>User Input prompts</h3>

	<p>I&#8217;ll write more about this in future posts, but for now, take as an ultimate example the <a href="http://thepowershellguy.com/blogs/posh/archive/2008/05/13/powershell-wmi-exporer-wpf-edition.aspx">latest post from mow, The PowerShell Guy</a> in which he rewrites his PowerShell <a href="http://thepowershellguy.com/blogs/posh/archive/tags/WMI+Explorer/"><span class="caps">WMI</span> Explorer</a> to be <span class="caps">WPF</span> based &#8212; it seems to not only run faster, but be based on less code (of course, that might just be because he&#8217;s gained experience since the first version).</p>

	<h3>Data-bound Graphs</h3>

	<p><a href='http://HuddledMasses.org/wpf-from-powershell-something-useful/out-bargraph/' rel="attachment wp-att-531"><img src="http://HuddledMasses.org/wordpress/wp-content/uploads/2008/05/out-bargraph.png" alt="A WPF databound bar graph dialog from PowerShell" title="out-bargraph" class="alignleft size-thumbnail wp-image-531" style="float:left; width:400px;" /></a>There are dozens of ways you can do data-bound graphs in PowerShell &#8212; including 3d &#8212; but the simplest to demonstrate (and coincidentally the easiest for me to come up with a use-case for) is a plain bar graph.  I&#8217;ve written a <a href='http://HuddledMasses.org/wpf-from-powershell-something-useful/graph/' rel='attachment wp-att-533'>simple graph window in XAML</a>, and created a script <a href='http://HuddledMasses.org/wordpress/wp-content/uploads/2008/05/out-bargraph.ps1'><code>Out-BarGraph</code></a> which lets you send data to it &#8230; but there are, as the Genie says, some caveats, provisos, addendums, and quid pro quos.  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=';)' class='wp-smiley' />  <span id="more-530"></span></p>

	<p>The main catch is that you <strong>have</strong> to specify the ScriptBlock parameters so that the script can figure out which properties to use as the Labels and Values &#8212; the purpose of this script is not to provide the most efficient way to bind PowerShell data to <span class="caps">WPF</span>, but rather to bind the data in a way that is easily translatable to new data types &#8212; because of this, you can use the script with file sizes, web traffic logs, performance monitor data, etc.</p>

	<p>The second catch is that we export the data to a temp file. In order to make it easy to handle multiple data-types, the <span class="caps">WPF</span> actually databinds to <span class="caps">XML</span> which we create by using PowerShell&#8217;s built in <code>Export-CliXml</code> cmdlet. The only constraint that whatever is exported must have three specific properties (Label, Value, Percentage) which the <code>Out-GraphableXml</code> function in the script calculates using script blocks you provide. I chose to do this so that you could see that you could create the xml from anywhere easily &#8230; but <em>you</em> could choose to databind to actual objects instead.</p>

	<p>Finally, there are a few additional constraints. This bar graph doesn&#8217;t update itself &#8212; it&#8217;s just a static graph of a given set of data.  It can&#8217;t represent negative numbers.  You <strong>must</strong> provide the <em>percentage</em> attribute as a number between 0 and 1 (again, in my example script the <code>Out-GraphableXml</code> function in the script calculates the percent based on the largest value).</p>

	<h4>The Script</h4>

	<p>Having laid out the shortcomings of the script, let me present it to you here in full glory.  Unlike the downloadable version linked above, this script includes the <span class="caps">XAML</span> source in-line as a <code>Data</code> block, so the entire script and UI code are in a single file.  Scroll to the end of the script for some explanations&#8230;</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;">#requires -version 2</span><br />
<span style="color: #666666; font-style: italic;">## Out-BarGraph.ps1</span><br />
<span style="color: #666666; font-style: italic;">## A script to generate WPF bargraphs using XAML</span><br />
<span style="color: #666666; font-style: italic;">## REQUIRES graph.xaml ( included here as a DATA section )</span><br />
<span style="color: #666666; font-style: italic;">########################################################################################################################</span><br />
<span style="color: #666666; font-style: italic;">## Example Usage</span><br />
<span style="color: #666666; font-style: italic;">## ls | Out-BarGraph &quot;File Sizes in Bytes&quot; -Label {$_.Name} -Value {$_.Length}</span><br />
<span style="color: #666666; font-style: italic;">########################################################################################################################</span><br />
<span style="color: #666666; font-style: italic;">## Version History</span><br />
<span style="color: #666666; font-style: italic;">## 1.4 &nbsp; - Embedded XAML in script</span><br />
<span style="color: #666666; font-style: italic;">## 1.3 &nbsp; - Added [scriptblock] parameters, removing need for data to be a custom psobject</span><br />
<span style="color: #666666; font-style: italic;">## 1.2 &nbsp; - Wrapper script now sets all values</span><br />
<span style="color: #666666; font-style: italic;">## 1.1.3 - Added data-bound &quot;scale&quot; labels</span><br />
<span style="color: #666666; font-style: italic;">## 1.1.2 - Added data-bound caption</span><br />
<span style="color: #666666; font-style: italic;">## 1.1.1 - Added data-bound labels</span><br />
<span style="color: #666666; font-style: italic;">## 1.1 &nbsp; - Got data-binding to the graph working</span><br />
<span style="color: #666666; font-style: italic;">## 1.0 &nbsp; - First working version, no live data binding</span><br />
<span style="color: #666666; font-style: italic;">########################################################################################################################</span><br />
<br />
<span style="color: #666699; font-weight: bold;">Param</span><span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$caption</span><span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;A bar-graph from WPF&quot;</span>, <br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$data</span> <span style="color: #66cc66;">=</span> @<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span>, <br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">scriptblock</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Label</span> <span style="color: #66cc66;">=</span> $<span style="color: #333;">&#40;</span><span style="color: #666699; font-weight: bold;">Throw</span> <span style="color: #009900;">&quot;You must specify the 'Label' scriptblock&quot;</span><span style="color: #333;">&#41;</span>,<br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">scriptblock</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Value</span> <span style="color: #66cc66;">=</span> $<span style="color: #333;">&#40;</span><span style="color: #666699; font-weight: bold;">Throw</span> <span style="color: #009900;">&quot;You must specify the 'Value' scriptblock&quot;</span><span style="color: #333;">&#41;</span>,<br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #666699; font-weight: bold;">switch</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$sideways</span><br />
<span style="color: #333;">&#41;</span><br />
<span style="color: #666699; font-weight: bold;">BEGIN</span> <span style="color: #333;">&#123;</span><br />
<span style="color: #666699; font-weight: bold;">DATA</span> XAML <span style="color: #333;">&#123;</span><br />
@<span style="color: #009900;">&quot;&lt;Window &nbsp;xmlns=&quot;</span>http:<span style="color: #66cc66;">//</span>schemas.<span style="color: #003366;">microsoft</span>.<span style="color: #003366;">com</span><span style="color: #66cc66;">/</span>winfx<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2006</span><span style="color: #66cc66;">/</span>xaml<span style="color: #66cc66;">/</span>presentation<span style="color: #009900;">&quot; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xmlns:x=&quot;</span>http:<span style="color: #66cc66;">//</span>schemas.<span style="color: #003366;">microsoft</span>.<span style="color: #003366;">com</span><span style="color: #66cc66;">/</span>winfx<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2006</span><span style="color: #66cc66;">/</span>xaml<span style="color: #009900;">&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xmlns:system=&quot;</span>clr<span style="color: #66cc66;">-</span>namespace:System;assembly<span style="color: #66cc66;">=</span>mscorlib<span style="color: #009900;">&quot; WindowStartupLocation='CenterScreen' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WindowStyle=&quot;</span>ToolWindow<span style="color: #009900;">&quot; ShowInTaskbar='True' SizeToContent='Width' Height=&quot;</span><span style="color: #cc66cc;">400</span><span style="color: #009900;">&quot; Width=&quot;</span><span style="color: #cc66cc;">600</span><span style="color: #009900;">&quot;&gt;<br />
&nbsp; &nbsp;&lt;Window.Resources&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;system:String x:Key=&quot;</span>GraphCaption<span style="color: #009900;">&quot;&gt;-&lt;/system:String&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;RotateTransform x:Key=&quot;</span>Vertical<span style="color: #009900;">&quot; Angle=&quot;</span><span style="color: #66cc66;">-</span><span style="color: #cc66cc;">90</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;RotateTransform x:Key=&quot;</span>Sideways<span style="color: #009900;">&quot; Angle=&quot;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;XmlNamespaceMappingCollection x:Key=&quot;</span>PowerShellMappings<span style="color: #009900;">&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;XmlNamespaceMapping Uri=&quot;</span>http:<span style="color: #66cc66;">//</span>schemas.<span style="color: #003366;">microsoft</span>.<span style="color: #003366;">com</span><span style="color: #66cc66;">/</span><span style="color: #003366; font-weight: bold;">powershell</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2004</span><span style="color: #66cc66;">/</span>04<span style="color: #009900;">&quot; Prefix=&quot;</span><span style="color: #660033;">ps</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;/XmlNamespaceMappingCollection&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;XmlDataProvider x:Key=&quot;</span><span style="color: #666699; font-weight: bold;">Data</span><span style="color: #009900;">&quot; XPath=&quot;</span><span style="color: #66cc66;">/</span><span style="color: #660033;">ps</span>:Objs<span style="color: #66cc66;">/</span><span style="color: #660033;">ps</span>:Obj<span style="color: #009900;">&quot; XmlNamespaceManager=&quot;</span><span style="color: #333;">&#123;</span>StaticResource PowerShellMappings<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Source=&quot;</span>C:\Users\JBennett\Documents\WindowsPowerShell\Scripts\Demo\<span style="color: #666699; font-weight: bold;">data</span>.<span style="color: #003366; font-weight: bold;">xml</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;XmlDataProvider x:Key=&quot;</span>scale<span style="color: #009900;">&quot; XPath=&quot;</span><span style="color: #66cc66;">/</span>scale<span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;DataTemplate x:Key=&quot;</span>SeriesLabels<span style="color: #009900;">&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Height=&quot;</span><span style="color: #cc66cc;">28</span><span style="color: #009900;">&quot; Margin=&quot;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span><span style="color: #009900;">&quot; HorizontalContentAlignment=&quot;</span>Right<span style="color: #009900;">&quot; LayoutTransform=&quot;</span><span style="color: #333;">&#123;</span>StaticResource Vertical<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding &nbsp;XPath<span style="color: #66cc66;">=*/*</span><span style="color: #333;">&#91;</span>@N\<span style="color: #66cc66;">=</span>\<span style="color: #009900;">'Label\'</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;/DataTemplate&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;DataTemplate x:Key=&quot;</span>bars<span style="color: #009900;">&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Rectangle Width=&quot;</span><span style="color: #cc66cc;">28</span><span style="color: #009900;">&quot; Margin=&quot;</span><span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span><span style="color: #009900;">&quot; Fill=&quot;</span>Red<span style="color: #009900;">&quot; RenderTransformOrigin=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">1</span><span style="color: #009900;">&quot; ToolTip=&quot;</span><span style="color: #333;">&#123;</span>Binding XPath<span style="color: #66cc66;">=*/*</span><span style="color: #333;">&#91;</span>@N\<span style="color: #66cc66;">=</span>\<span style="color: #009900;">'Value\'</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#125;</span><span style="color: #009900;">&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Rectangle.RenderTransform&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;ScaleTransform x:Name=&quot;</span>Scaler<span style="color: #009900;">&quot; ScaleX=&quot;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&quot; ScaleY=&quot;</span><span style="color: #333;">&#123;</span>Binding XPath<span style="color: #66cc66;">=*/*</span><span style="color: #333;">&#91;</span>@N\<span style="color: #66cc66;">=</span>\<span style="color: #009900;">'Percent\'</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/Rectangle.RenderTransform&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/Rectangle&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;/DataTemplate&gt;<br />
&nbsp; &nbsp;&lt;/Window.Resources&gt;<br />
&lt;DockPanel Margin=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&quot;&gt;<br />
&lt;Label DockPanel.Dock=&quot;</span>Top<span style="color: #009900;">&quot; HorizontalAlignment=&quot;</span>Center<span style="color: #009900;">&quot; FontFamily=&quot;</span>Garamond<span style="color: #009900;">&quot; FontSize=&quot;</span><span style="color: #cc66cc;">20</span><span style="color: #009900;">&quot; <br />
&nbsp; &nbsp; &nbsp; &nbsp;Content=&quot;</span><span style="color: #333;">&#123;</span>DynamicResource GraphCaption<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;Grid LayoutTransform=&quot;</span><span style="color: #333;">&#123;</span>DynamicResource Sideways<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; Name=&quot;</span>Graph<span style="color: #009900;">&quot; ShowGridLines=&quot;</span>True<span style="color: #009900;">&quot; &gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Grid.ColumnDefinitions&gt;&lt;ColumnDefinition Width=&quot;</span>Auto<span style="color: #009900;">&quot;/&gt;&lt;ColumnDefinition Width=&quot;</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;/Grid.ColumnDefinitions&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Grid.RowDefinitions&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">*</span><span style="color: #009900;">&quot;/&gt;&lt;RowDefinition Height=&quot;</span>Auto<span style="color: #009900;">&quot;/&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/Grid.RowDefinitions&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">4</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">5</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">6</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">6</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">8</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">9</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot; /&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;Label Grid.Row=&quot;</span><span style="color: #cc66cc;">9</span><span style="color: #009900;">&quot; Padding=&quot;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&quot; Content=&quot;</span><span style="color: #333;">&#123;</span>Binding Source<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span>StaticResource scale<span style="color: #333;">&#125;</span>, XPath<span style="color: #66cc66;">=//</span>Mark<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #333;">&#93;</span><span style="color: #66cc66;">/</span>@Label<span style="color: #333;">&#125;</span><span style="color: #009900;">&quot;/&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;ItemsControl Name=&quot;</span>Bars<span style="color: #009900;">&quot; Grid.RowSpan=&quot;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&quot; Grid.Column=&quot;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&quot; Background=&quot;</span><span style="color: #666666; font-style: italic;">#FFD7F39F&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ItemsSource<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;{Binding Source={StaticResource Data}}&quot;</span> ItemTemplate<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;{StaticResource bars}&quot;</span> <span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&lt;</span>ItemsControl.<span style="color: #003366;">ItemsPanel</span><span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&lt;</span>ItemsPanelTemplate<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&lt;</span>StackPanel Orientation<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Horizontal&quot;</span><span style="color: #66cc66;">/&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&lt;/</span>ItemsPanelTemplate<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&lt;/</span>ItemsControl.<span style="color: #003366;">ItemsPanel</span><span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&lt;/</span>ItemsControl<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&lt;</span>ItemsControl Name<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;SeriesLabels&quot;</span> Grid.<span style="color: #003366;">Column</span><span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;1&quot;</span> Grid.<span style="color: #003366;">Row</span><span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;11&quot;</span> Margin<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;0,0,0,0&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ItemsSource<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;{Binding Source={StaticResource Data}}&quot;</span> ItemTemplate<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;{StaticResource SeriesLabels}&quot;</span> <span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&lt;</span>ItemsControl.<span style="color: #003366;">ItemsPanel</span><span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&lt;</span>ItemsPanelTemplate<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&lt;</span>StackPanel Orientation<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Horizontal&quot;</span><span style="color: #66cc66;">/&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&lt;/</span>ItemsPanelTemplate<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&lt;/</span>ItemsControl.<span style="color: #003366;">ItemsPanel</span><span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&lt;/</span>ItemsControl<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&lt;/</span>Grid<span style="color: #66cc66;">&gt;</span><br />
&nbsp; &nbsp;<span style="color: #66cc66;">&lt;/</span>DockPanel<span style="color: #66cc66;">&gt;</span><br />
<span style="color: #66cc66;">&lt;/</span>Window<span style="color: #66cc66;">&gt;</span><br />
<span style="color: #009900;">&quot;@<br />
}<br />
&nbsp; &nbsp;function Out-GraphableXml ($data, [ref]$max, [scriptblock]$Label, [scriptblock]$Value) {<br />
&nbsp; &nbsp; &nbsp; ### Get a &quot;</span>Max<span style="color: #009900;">&quot; number which should be the next big round number (eg: 5,10,50,100,150 ...)<br />
&nbsp; &nbsp; &nbsp; $max.Value = ($data | Sort-Object {&amp;$Value -as [double]} -Desc | Select-Object @{n=&quot;</span>Value<span style="color: #009900;">&quot;;e=$Value} -First 1).Value -as [double]<br />
&nbsp; &nbsp; &nbsp; if( $max.Value -gt 1 ) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$siz = [Math]::Pow( 10, [Math]::Truncate($max.Value).ToString().Length -1 ) / 2<br />
&nbsp; &nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$siz = (.5 / (10 * ($max.Value.ToString().Length - 2 - $max.Value.ToString().TrimStart(&quot;</span>0.<span style="color: #009900;">&quot;).Length)))<br />
&nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; $max.Value = [Math]::Ceiling( $max.Value / $siz ) * $siz<br />
<br />
&nbsp; &nbsp; &nbsp; ## Export the data ...<br />
&nbsp; &nbsp; &nbsp; $path = [IO.Path]::GetTempFileName()<br />
&nbsp; &nbsp; &nbsp; $data | Select-Object @{n=&quot;</span>Value<span style="color: #009900;">&quot;;e=$Value},@{n=&quot;</span>Label<span style="color: #009900;">&quot;;e=$Label},@{n=&quot;</span>Percent<span style="color: #009900;">&quot;;e={($_ | &amp;$Value)/$max.Value}} | export-clixml $path<br />
&nbsp; &nbsp; &nbsp; return $path<br />
&nbsp; &nbsp;}<br />
}<br />
<br />
PROCESS {<br />
&nbsp; &nbsp;if($_) {<br />
&nbsp; &nbsp; &nbsp; $data += $_<br />
&nbsp; &nbsp;}<br />
}<br />
END {<br />
&nbsp; &nbsp;Write-Host &quot;</span>Loading XAML window...<span style="color: #009900;">&quot; -fore Cyan<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;### Import the WPF assemblies<br />
&nbsp; &nbsp;Add-Type -Assembly PresentationFramework<br />
&nbsp; &nbsp;Add-Type -Assembly PresentationCore<br />
&nbsp; &nbsp;## I've removed the xaml to a separate document because it's getting too big for my example :)<br />
&nbsp; &nbsp;$graph = [Windows.Markup.XamlReader]::Load( (New-Object System.Xml.XmlNodeReader ([Xml]$XAML)) )<br />
&nbsp; &nbsp;$graph.Resources.Data.Source = Out-GraphableXml $data ([ref]$max) $Label $Value<br />
<br />
&nbsp; &nbsp;### Generate 10 labels ...<br />
&nbsp; &nbsp;$graph.Resources.scale.Document = &amp;{ <br />
&nbsp; &nbsp; &nbsp; &quot;</span><span style="color: #66cc66;">&lt;</span>scale xmlns<span style="color: #66cc66;">=</span><span style="color: #009900;">''</span><span style="color: #66cc66;">&gt;</span><span style="color: #009900;">&quot;<br />
&nbsp; &nbsp;10..1 | ForEach-Object { &quot;</span><span style="color: #66cc66;">&lt;</span>Mark Label<span style="color: #66cc66;">=</span><span style="color: #009900;">'$(($max/10)*$_)'</span> <span style="color: #66cc66;">/&gt;</span><span style="color: #009900;">&quot; }<br />
&nbsp; &nbsp; &nbsp; &quot;</span><span style="color: #66cc66;">&lt;/</span>scale<span style="color: #66cc66;">&gt;</span><span style="color: #009900;">&quot;<br />
&nbsp; &nbsp;}<br />
&nbsp; &nbsp;### And set the caption<br />
&nbsp; &nbsp;$graph.Resources.GraphCaption = $caption<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;### Maybe rotate the whole thing<br />
&nbsp; &nbsp;if($sideways) {<br />
&nbsp; &nbsp; &nbsp; $graph.Resources.Sideways.Angle = 90<br />
&nbsp; &nbsp;}<br />
<br />
&nbsp; &nbsp;$graph.ShowDialog()<br />
&nbsp; &nbsp;# Don't forget to delete that temp file...<br />
&nbsp; &nbsp;Remove-Item $graph.Resources.Data.Source.AbsolutePath<br />
}</span></div>

	<h4>Some <span class="caps">XAML</span> Tips</h4>

	<p>I learned a few things about <span class="caps">XAML</span> markup while doing this. 
	<ol>
		<li>If you bind to an <span class="caps">XML</span> data source that&#8217;s in-line in your <span class="caps">XAML</span>, you do so using the <code>x:XData</code> element, and then a single root element <em>inside</em> that.  You <em>must</em> specify a blank <code>xmlns</code> parameter on that root element, or it won&#8217;t work.  However, when you bind to an eternal <span class="caps">XML</span> document, as in our case &#8212; you need to specify the <span class="caps">XML</span> namespaces using a <code>XmlNamespaceMapping</code> collection &#8212; and you <strong>must</strong> use a prefix, and then repeat that prefix throughout your Xaml whenever you specify an XPath.  However, attributes don&#8217;t require the prefix (I&#8217;m not actually sure why) so in the code above I simply used wildcards for practically every element.</li>
		<li>When you specify attribute <em>tests</em> (like /Node[<code>attribute=&#39;value&#39;]) in binding markup, you get an error because of the equals sign and quotes, but you can just escape them with a backslash, or you can use a </code>Binding@ element and put the test in the XPath attribute (which doesn&#8217;t need escaping).</li>
		<li>The <span class="caps">XAML</span> Grid element is the only element that supports proportional sizing and supports making all the things in a column (or row) the size of the largest item. It&#8217;s a pain to work with by hand because you have to specify each <code>RowDefinition</code> and <code>ColumnDefinition</code> and then assign each child control a <code>Grid.Column</code> and <code>Grid.Row</code> and possibly even a <code>Grid.ColumnSpan</code> or <code>Grid.RowSpan</code> &#8230;</li>
	</ol>
	<ol>
		<li>If you only learn two of the &#8220;complicated&#8221; controls, learn about Grid and <a href="http://www.drwpf.com/blog/Home/tabid/36/EntryID/13/Default.aspx">ItemsControl</a>.</li>
	</ol></p>

	<h4>Some PowerShell <span class="caps">WPF</span> Tips</h4>

	<ol>
		<li>You can generate <span class="caps">XML</span> using <a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx">XDocument</a> instead of <a href="http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx">XmlDocument</a>, but to be perfectly honest, since you&#8217;re already moving slow, the simplest way to write <span class="caps">XML</span> in PowerShell is to just use here-strings.  In fact, if you need to generate a bunch of rows of <span class="caps">XML</span>, this snippet should help send you in the right direction:<div class="posh code posh" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">XML</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$xml</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&amp;</span><span style="color: #333;">&#123;</span> <br />
<span style="color: #009900;">&quot;&lt;?xml version='1.0' encoding='UTF-8'?&gt;&quot;</span><br />
<span style="color: #009900;">&quot;&lt;scale xmlns=''&gt;&quot;</span><br />
10..1 <span style="color: #66cc66;">|</span> ForEach<span style="color: #66cc66;">-</span>Object <span style="color: #333;">&#123;</span> <span style="color: #009900;">&quot;&lt;Mark Label='$(($max/10)*$_)' /&gt;&quot;</span> <span style="color: #333;">&#125;</span><br />
<span style="color: #009900;">&quot;&lt;/scale&gt;&quot;</span><br />
<span style="color: #333;">&#125;</span></div></li>
		<li>Although the <code>about_data_section</code> help says that you can use [XML]&#8221;...&#8221; as a literal in a Data section &#8212; you can&#8217;t.  Just get used to casting it on the way out &#8230;  Also, </li>
		<li>If you need to cast a parameter to a function, (or specify it as a reference parameter) you have to enclose it in parenthesis: <code>Out-GraphableXml $data ([ref]$max) $Label $Value</code> &#8212; it&#8217;s not enough to put the type there.</li>
		<li>Don&#8217;t forget, reference parameters in PowerShell are actually a <strong>type</strong> (PSReference), and to access the variable inside a PSReference variable <code>$foo</code>, you have to use <code>$foo.Value</code>.</li>
	</ol>
	<ol>
		<li>Sometimes, the Dispatcher.Invoke trick isn&#8217;t enough &#8212; in the case of this data-bound form, it needs to go through at least 3 cycles of handling events before it will finish drawing:<div class="posh code posh" style="font-family:monospace;"><span style="color: #660033; font-weight: bold;">$graph</span>.<span style="color: #003366;">Show</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
1..3 <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">%</span><span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$graph</span>.<span style="color: #003366;">Dispatcher</span>.<span style="color: #003366;">Invoke</span><span style="color: #333;">&#40;</span> <span style="color: #009900;">&quot;Render&quot;</span>, <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Windows.<span style="color: #003366;">Input</span>.<span style="color: #003366;">InputEventHandler</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#123;</span> <span style="color: #333;">&#125;</span>, <span style="color: #660033; font-weight: bold;">$null</span>, <span style="color: #660033; font-weight: bold;">$null</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span></div></li>
	</ol>

]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/wpf-from-powershell-something-useful/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WPF From PowerShell &#8211; Updating Windows</title>
		<link>http://joelbennett.net/wpf-from-powershell-updating-windows/</link>
		<comments>http://joelbennett.net/wpf-from-powershell-updating-windows/#comments</comments>
		<pubDate>Fri, 09 May 2008 04:32:20 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Forms]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=524</guid>
		<description><![CDATA[In my last post I wrote about how you could make a WPF Splash screen window in PowerShell, but I stated that: &#8220;if the images are remote, the WPF window has to download them, and therefore won&#8217;t work&#8221; correctly. I had played with downloading images directly by setting the Source attribute of the image to [...]]]></description>
			<content:encoded><![CDATA[	<p>In my last post I wrote about how you could <a href="http://huddledmasses.org/wpf-from-powershell-a-splash-screen/">make a <span class="caps">WPF</span> Splash screen window in PowerShell</a>, but I stated that: &#8220;if the images are remote, the <span class="caps">WPF</span> window has to download them, and therefore won&#8217;t work&#8221; correctly.  I had played with downloading images directly by setting the <code>Source</code> attribute of the image to the image <span class="caps">URL</span>, and hadn&#8217;t been able to find a way to get the threading to work well enough to actually download the image.  </p>

	<p>Well, I figured that out, so I thought I&#8217;d go ahead and share &#8230; basically, all you have to do is call Invoke() on the window&#8217;s dispatcher.  The reason that works is that <span class="caps">WPF</span> handles events and &#8220;work&#8221; in general in the order it needs to be done, so since the most important thing is drawing the UI it will do that first, and since your UI is based on downloading the image, it will take care of that first.</p>

	<h6>This is PowerShell v2 CTP2 code&#8230;</h6>

	<p>All of this code is written to target the CTP2 release of PowerShell v2 &#8212; it <em>will not</em> work in PowerShell v1 or even in v2 CTP1 &#8230; and it <em>may not</em> work in later releases, although I expect it will.  Also, as with any code which uses <span class="caps">WPF</span> from PowerShell, these code examples require you to launch PowerShell with the -<span class="caps">STA</span> option.</p>

	<p>Having said that, lets just straight to a <span class="caps">WPF</span> example <span id="more-524"></span></p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666699; font-weight: bold;">function</span> demo2 <span style="color: #333;">&#123;</span><br />
<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Type</span></span> <span style="color: #000066;">-Assembly</span> PresentationFramework<br />
<br />
<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">xml</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$xaml</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;&lt;Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'<br />
&nbsp; &nbsp;WindowStyle='None' AllowsTransparency='True' Opacity='0.8' Topmost='True'<br />
&nbsp; &nbsp;SizeToContent='WidthAndHeight' WindowStartupLocation='CenterOwner' ShowInTaskbar='False'&gt;<br />
&lt;Image Height='177' Source='http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/00000/5000/500/5651/5651.strip.print.gif' /&gt;<br />
&lt;/Window&gt;&quot;</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$splash</span> <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Windows.<span style="color: #003366;">Markup</span>.<span style="color: #003366;">XamlReader</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">Load</span><span style="color: #333;">&#40;</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366; font-weight: bold;">Xml</span>.<span style="color: #003366;">XmlNodeReader</span> <span style="color: #660033; font-weight: bold;">$xaml</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#41;</span><br />
<span style="color: #660033; font-weight: bold;">$splash</span>.<span style="color: #003366;">Show</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
<span style="color: #660033; font-weight: bold;">$splash</span>.<span style="color: #003366;">Dispatcher</span>.<span style="color: #003366;">Invoke</span><span style="color: #333;">&#40;</span> <span style="color: #009900;">&quot;Render&quot;</span>, <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Windows.<span style="color: #003366;">Input</span>.<span style="color: #003366;">InputEventHandler</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$splash</span>.<span style="color: #003366;">UpdateLayout</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span>, <span style="color: #660033; font-weight: bold;">$null</span>, <span style="color: #660033; font-weight: bold;">$null</span><span style="color: #333;">&#41;</span><br />
<span style="color: #0066cc; font-style: italic;">Start-<span style="font-style: normal;">Sleep</span></span> <span style="color: #cc66cc;">3</span> &nbsp; <span style="color: #666666; font-style: italic;"># imagine this is a long script &nbsp;... running</span><br />
<span style="color: #660033; font-weight: bold;">$splash</span>.<span style="color: #003366;">Hide</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span> <span style="color: #666666; font-style: italic;"># and at the end, you just get rid of it</span><br />
<span style="color: #333;">&#125;</span></div>

	<p>That&#8217;s almost as simple as it could get, but let me explain a few things which I left out previously, in case you&#8217;re new to <span class="caps">XAML</span> or even <span class="caps">WPF</span>.  The <strong>Window</strong> tag is one of several acceptable root tags in <span class="caps">XAML</span>, but it&#8217;s the only one which will let you pop up a new window (in PoshConsole, you can display <span class="caps">XAML</span> inline using <code>Out-WPF</code>, and you can use almost any <span class="caps">XAML</span> nodes, but for now, lets focus on what works in general in the CTP2 console).  The <code>xmlns</code> attribute is required in order for the xml to be verifiable to the schema, but in <span class="caps">XAML</span> it&#8217;s particularly important because without it, this would just be <span class="caps">XML</span> &#8212;not Xaml&#8212; and wouldn&#8217;t produce UI.</p>

	<h3><span class="caps">WPF</span> Windows</h3>

	<p>There&#8217;s several fun tricks you can do in <span class="caps">WPF</span> with the Window that you can&#8217;t do in Windows Forms without a lot of hacking. <code>ShowInTaskbar</code> is hardly worth mentioning (it just does what it says). The <code>Opacity</code> attribute is kind of cool &#8212; it just controls the translucency level (valid values are from 0 to 1, but below the smaller values aren&#8217;t really very useful) &#8212; but you can animate this pretty easily to cause your windows to fade in and out.  But there are a few that are more impressive:</p>

	<h4>Size To Content</h4>

	<p>One of my favorite features of <span class="caps">WPF</span> windows it that you can use <code>SizeToContent</code> to have the form automatically take the size of whatever is inside it (which is really useful when you&#8217;re loading images off the web).  You have to be careful with this though, because <a href="http://www.wpflearningexperience.com/?p=41"><span class="caps">WPF</span> is resolution independent</a> but it&#8217;s also aware of how many pixels-per-inch images have been saved with.  Typically, if you have a png file, it&#8217;s been saved at something like 200 or 300 pixels per inch to make it printable &#8230; but your screen&#8217;s resolution is only (<a href="http://www.wpflearningexperience.com/?p=41">approximately</a>) 96 pixels-per-inch.  This results in images being displayed, by default &#8230; at <span class="caps">HUGE</span> sizes compared to what you expect. Caveat emptor.</p>

	<h4>Transparency</h4>

	<p>A <span class="caps">WPF</span> window with <code>AllowsTransparency</code> set to true can be non-rectangular!  It&#8217;s <strong>very</strong> important that you understand this isn&#8217;t about allowing translucency (that is, it has nothing to do with the Opacity setting). With this setting on, your window will basically not exist in any spot where there&#8217;s no color (See demo4 below). It will be not only be invisible &#8212; mouse-clicks won&#8217;t register.  You&#8217;ll also be able to have true per-pixel transparency, with the ability to set the alpha level of each pixel, since <span class="caps">WPF</span> colors can be specified as #<span class="caps">AARRGGBB</span> quads.</p>

	<h4>WindowStyle</h4>

	<p>This wouldn&#8217;t merit mentioning, except that it has a tie-in with Transparency. You can set the <code>WindowStyle</code> in Windows Forms too, and just like Windows Forms, the valuesfor <span class="caps">WPF</span> are None, SingleBorderWindow, ThreeDBorderWindow, and ToolWindow &#8230; however, if you use AllowsTransparency, the only valid value for WindowStyle is &#8220;None.&#8221;</p>

	<h4>Startup Location</h4>

	<p>As with <code>WindowStyle</code>, this attribute is mostly special because of it&#8217;s exceptions. You can use <code>WindowStartupLocation</code> to specify where you want the form to appear. Valid values are Manual, CenterScreen, and CenterOwner.  CenterScreen is the obvious choice for a splash screen, but I should point out something about the other two as well. CenterOwner means to center the window on it&#8217;s parent window &#8230; but it only works with other <span class="caps">WPF</span> windows. If you don&#8217;t set the owner to a <span class="caps">WPF</span> window, CenterOwner works just like Manual.  The Manual setting allows you to specify the window position with the <code>Top</code> and <code>Left</code> attributes, or just let Windows position you in the default location.</p>

	<h3>Events and Delegates</h3>

	<p>There&#8217;s one line of code in the sample above which bears explaining &#8212; the call to <code>Dispatcher.Invoke</code>. The point of this call is to basically transfer the thread control to the window for a moment. In fact, the signature of the Invoke method is that it takes a <em>priority</em> (I use render because it&#8217;s basically immediate), a <em>delegate</em> (I pass a scriptblock), and arguments for the scriptblock.  PowerShell will let you <em>easily</em> cast a scriptblock to a delegate method which takes two <code>object</code> parameters and doesn&#8217;t return a value &#8230; but it won&#8217;t let you convert them to any other method without using reflection and <code>IL.Emit</code>.  Thus, we cast our scriptblock to any handy delegate type, and pass <code>$null</code> for both parameters.</p>

	<h3>But that Invoke() stuff is ugly</h3>

	<p>Of course, we don&#8217;t like having to manually update the window by calling Invoke(), but I still haven&#8217;t figured out how to spin out another thread safely &#8230; so the only other option is to just give control to the window (actually I think this could be done with background jobs, but I can&#8217;t seem to get the WinRM <span class="caps">CTP</span> configured properly).</p>

	<p>Giving control to the window is actually the <em>normal</em> way of doing UI programming &#8230; and isn&#8217;t really a very big deal in PowerShell &#8212; you can write your event handlers for the controls on the window, and then call ShowDialog() and you&#8217;re off.  Just to give you an example, I&#8217;ve tweaked an old <span class="caps">WPF</span> sample I had and ported it to PowerShell &#8230;  the <a href='http://HuddledMasses.org/wpf-from-powershell-updating-windows/clock/' rel='attachment wp-att-528'>xaml file is here</a> and I&#8217;ll paste the code (with comments) inline, but if you may also <a href='http://HuddledMasses.org/wpf-from-powershell-updating-windows/demo-wpf4/' rel='attachment wp-att-529'>download the PowerShell script</a>.  You need both files for it to work, because the clock.xaml file is the only argument to the demo-wpf4.ps1 script  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=':)' class='wp-smiley' /> </p>

	<p>Check it out:</p>

	<p><img src="http://huddledmasses.org/images/2008-05-09_0029.png" title="A clock, with working CPU and RAM bars" alt="A clock, with working CPU and RAM bars" width="783" height="312" /></p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;">### Import the WPF assemblies</span><br />
<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Type</span></span> <span style="color: #000066;">-Assembly</span> PresentationFramework<br />
<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Type</span></span> <span style="color: #000066;">-Assembly</span> PresentationCore<br />
<br />
<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;Initializing Performance Counters, please have patience&quot;</span> <span style="color: #000066;">-fore</span> Cyan<br />
<span style="color: #660033; font-weight: bold;">$script</span>:cpu <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">object</span></span> System.<span style="color: #003366;">Diagnostics</span>.<span style="color: #003366;">PerformanceCounter</span> <span style="color: #009900;">&quot;Processor&quot;</span>, <span style="color: #009900;">&quot;% Processor Time&quot;</span>, <span style="color: #009900;">&quot;_Total&quot;</span><br />
<span style="color: #660033; font-weight: bold;">$script</span>:ram <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">object</span></span> System.<span style="color: #003366;">Diagnostics</span>.<span style="color: #003366;">PerformanceCounter</span> <span style="color: #009900;">&quot;Memory&quot;</span>, <span style="color: #009900;">&quot;Available KBytes&quot;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## get initial values, because the counters don't work until the second call</span><br />
<span style="color: #660033; font-weight: bold;">$null</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$script</span>:cpu.<span style="color: #003366;">NextValue</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
<span style="color: #660033; font-weight: bold;">$null</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$script</span>:ram.<span style="color: #003366;">NextValue</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
<span style="color: #660033; font-weight: bold;">$script</span>:maxram <span style="color: #66cc66;">=</span> <span style="color: #333;">&#40;</span><span style="color: #660033;">gwmi</span> Win32_OperatingSystem<span style="color: #333;">&#41;</span>.<span style="color: #003366;">TotalVisibleMemorySize</span><br />
<br />
<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;Loading XAML window...&quot;</span> <span style="color: #000066;">-fore</span> Cyan<br />
<span style="color: #666666; font-style: italic;">## I've removed the xaml to a separate document because it's getting too big for my example :)</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$clock</span> <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Windows.<span style="color: #003366;">Markup</span>.<span style="color: #003366;">XamlReader</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">Load</span><span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> System.<span style="color: #003366; font-weight: bold;">Xml</span>.<span style="color: #003366;">XmlNodeReader</span> <span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Xml</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Content</span></span> <span style="color: #009900;">&quot;C:\Users\Joel\Documents\WindowsPowerShell\Scripts\Demo\clock.xaml&quot;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#41;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Create a script block which will update the UI</span><br />
<span style="color: #660033; font-weight: bold;">$counter</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>;<br />
<span style="color: #660033; font-weight: bold;">$updateBlock</span> <span style="color: #66cc66;">=</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Update the clock</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Resources</span><span style="color: #333;">&#91;</span><span style="color: #009900;">&quot;Time&quot;</span><span style="color: #333;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>DateTime<span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">Now</span>.<span style="color: #003366;">ToString</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;hh:MM.ss&quot;</span><span style="color: #333;">&#41;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># We only want to update the counters at most once a second</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Otherwise their values are invalid and ...</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># The CPU counter fluctuates from 0 to the real number</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$counter</span><span style="color: #66cc66;">++</span> <span style="color: #000066;">-eq</span> <span style="color: #cc66cc;">4</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$counter</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Update the CPU counter</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$cu</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$cpu</span>.<span style="color: #003366;">NextValue</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Resources</span>.<span style="color: #003366;">CpuP</span> <span style="color: #66cc66;">=</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$cu</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">100</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Resources</span>.<span style="color: #003366;">Cpu</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;{0:0.0}%&quot;</span> <span style="color: #000066;">-f</span> <span style="color: #660033; font-weight: bold;">$cu</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">#$clock.FindResource(&quot;CpuStory&quot;).Begin($clock)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Update the RAM counter</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$rm</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$ram</span>.<span style="color: #003366;">NextValue</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Resources</span>.<span style="color: #003366;">RamP</span> <span style="color: #66cc66;">=</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$rm</span> <span style="color: #66cc66;">/</span> <span style="color: #660033; font-weight: bold;">$maxram</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Resources</span>.<span style="color: #003366;">Ram</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;{0:0.00}Mb&quot;</span> <span style="color: #000066;">-f</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$rm</span><span style="color: #66cc66;">/</span>1MB<span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">#$clock.FindResource(&quot;RamStory&quot;).Begin()</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Hook up some event handlers </span><br />
<span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Add_SourceInitialized</span><span style="color: #333;">&#40;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## Before the window's even displayed ...</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## We'll create a timer</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$timer</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">object</span></span> System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Threading</span>.<span style="color: #003366;">DispatcherTimer</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## Which will fire 4 times every second</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$timer</span>.<span style="color: #003366;">Interval</span> <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>TimeSpan<span style="color: #333;">&#93;</span></span><span style="color: #009900;">&quot;0:0:0.25&quot;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## And will invoke the $updateBlock</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$timer</span>.<span style="color: #003366;">Add_Tick</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$updateBlock</span> <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## Now start the timer running</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$timer</span>.<span style="color: #660033;">Start</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$timer</span>.<span style="color: #003366;">IsEnabled</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;Clock is running. Don't forget: RIGHT-CLICK to close it.&quot;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Close</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Error</span></span> <span style="color: #009900;">&quot;Timer didn't start&quot;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span> <span style="color: #333;">&#41;</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Add_MouseLeftButtonDown</span><span style="color: #333;">&#40;</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Handled</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$true</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">DragMove</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span> <span style="color: #666666; font-style: italic;"># WPF Magic!</span><br />
<span style="color: #333;">&#125;</span> <span style="color: #333;">&#41;</span><br />
<span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Add_MouseRightButtonDown</span><span style="color: #333;">&#40;</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Handled</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$true</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$timer</span>.<span style="color: #003366;">Stop</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span> &nbsp;<span style="color: #666666; font-style: italic;"># we'd like to stop that timer now, thanks.</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">Close</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span> <span style="color: #666666; font-style: italic;"># and close the windows</span><br />
<span style="color: #333;">&#125;</span> <span style="color: #333;">&#41;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Lets go ahead and invoke that update block </span><br />
<span style="color: #66cc66;">&amp;</span><span style="color: #660033; font-weight: bold;">$updateBlock</span><br />
<span style="color: #666666; font-style: italic;">## And then show the window</span><br />
<span style="color: #660033; font-weight: bold;">$clock</span>.<span style="color: #003366;">ShowDialog</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span></div>

	<h4> <img src='http://joelbennett.net/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  Post Script</h4>

	<p>I should probably mention that I coded the <span class="caps">XAML</span> for that clock by hand, using <a href="http://www.kaxaml.com/">kaxaml</a>, rather than using Expression Blend &#8212; I don&#8217;t necessarily recommend it, but it&#8217;s good practice once in a while.  <img src='http://joelbennett.net/wordpress/wp-includes/' alt=':)' class='wp-smiley' />   <span class="caps">XAML</span> supports a lot of animations, and I spent almost an entire day trying different things to create a smooth animation for the <span class="caps">CPU</span> and <span class="caps">RAM</span> bars which would let them animate smoothly from one value to the next.  In the end I decided it would have to be written in code rather than <span class="caps">XAML</span> markup, and would complicate things even more than they already were.</p>]]></content:encoded>
			<wfw:commentRss>http://joelbennett.net/wpf-from-powershell-updating-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

