Blend -> XAML -> PowerShell

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

image

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

image

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

Comments (4) -

Excellent.  Now even GUIdiots like me can create XAML forms.

Nice concise post on Xaml, PowerShell and WPF

hmm i'm having a slight problem getting this to work:

PS>$d = [Windows.Markup.XamlReader]::Load($reader)

Unable to find type [Windows.Markup.XamlReader]: make sure that the assembly containing this type is loaded.
At line:1 char:34
+ ($d = [Windows.Markup.XamlReader] <<< $new
    + CategoryInfo          : InvalidOperation: (Windows.Markup.XamlReader:String) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

Add-Type -AssemblyName presentationframework

before everything else for it to work.

Comments are closed