The PowerShell team just posted a blog entry with slides and demo scripts for one of their presentations from TechEd 2009. There is a lot of cool stuff in their but one thing that piqued my interested was the GUI Demo using WPF. I noticed in the demo scripts that they had a PS1 script and a XAML file. I could try to describe XAML but I will leave that to the guys that literally wrote the book.
“XAML is an XML-based language for creating and initializing .NET objects. It’s used in WPF as a human-authorable way of describing the UI.” - “Programming WPF, by Chris Sells and Ian Griffiths, page 8
Expression Blend is a Microsoft product that allows designers to create UI’s in a sort of similar way that you could create WinForms using the WinForms designer in Visual Studio. It’s all drag ‘n drop. Blend is essentially a Winforms designer for WPF. It definitely takes some getting used to but the bottom line is that you don’t need to know how to code to get some basic windows, shapes, and controls up and running.
Here is a (not so) beautiful dialog box with a rectangle and a big button

Well, in Blend, if you click on XAML tab you can see the angle brackets that make up this UI.
What’s cool is that you can use this XAML that was created with Blend in PowerShell.
We can accomplish this using a [Windows.Markup.XamlReader] and call that Load static Method. Assuming we store the XAML in a here string, you just need to cast it to XML and pass it in like so
$reader = New-Object System.Xml.XmlNodeReader $xaml
$d = [Windows.Markup.XamlReader]::Load($reader)
Once you have $d you can do a bunch of things with it.
$d.ShowDialog() will display the dialog box as the script below demonstrates.
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036
|
[xml]$xaml = @" <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Window" Title="Blend and PowerShell" Width="640" Height="480" AllowsTransparency="False"> <Grid x:Name="LayoutRoot"> <Button HorizontalAlignment="Right" Margin="0,0,153,194" VerticalAlignment="Bottom" Width="5" Height="2" Content="Button"/> <Rectangle Margin="22,8,22,0" VerticalAlignment="Top" Height="178" Stroke="#FF000000"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF000000" Offset="0"/> <GradientStop Color="#FF861A1A" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Button Margin="121,0,129,96" VerticalAlignment="Bottom" Height="100" Content="Button" x:Name="Close"/> </Grid> </Window> "@ $reader = New-Object System.Xml.XmlNodeReader $xaml $d = [Windows.Markup.XamlReader]::Load($reader) $d.ShowDialog() | out-null
|
When I run this, I get the following

You may notice I tweaked the XAML a little bit. I changed the Window title on line 6. Blend also adds a class to its <Window> tag that is associated with the project in Blend. I had to remove that to get it to work in PowerShell. Other than that, we basically have a WPF editor that can create XAML that can be used in PowerShell.
My next post will deal with events. I do suppose it would be nice if clicking the button actually did something, huh.
Until next time..
Andy