WPF & PowerShell – Part 2 (Exploring WPF (and the rest of .NET) with Scripts)

In my previous post, I showed you how to create “Hello World” scripts using Windows Presentation Foundation (WPF) and Windows PowerShell.


While “Hello World” is relatively easy to write with WPF, it is only the tip of the iceberg of the types of quick user interfaces you can write.


Windows Presentation Foundation provides an amazing array of controls for an incredible array of purposes.  Out of the box, with just one control, you can:


·         Show a listbox


·         Play a video or audio file


·         Capture user drawings


·         Display an image


·         Draw a complex polygon


·         Display a slider


 


All controls can use video, images, gradients, and rich colors as their background or foreground.  All controls can interact with Tablet PC input, Keyboard, and Mouse.  All windows can be transparent.


 


In the vastness of WPF, there is not a Get-Command or a Get-Help to help you discover what you can do with WPF.  The existence of Get-Command and Get-Help is one of my favorite things about PowerShell, because it helps close what I call the Discoverability Gap.   The Discoverability Gap is the difficulty in a scripter of developer determining what solutions exist for a problem.


 


While PowerShell has an elegant solution to the Discoverability Gap, there have been many good attempts in the past.  .NET’s is refection.  In this post I’ll give you a couple of functions that help close the Discoverability Gap for .NET, and then show you how to find examples on MSDN.


 


You’ll need three functions for the fun.  They’re all one liners.


 


# Looks returns all of the .NET types currently loaded by PowerShell


function Get-Type() { [AppDomain]::CurrentDomain.GetAssemblies() | % { $_.GetTypes() }}


                                                                 


# Opens a webpage to connect to look up information about the Type on MSDN (e.g http://msdn.microsoft.com/en/library/System.Windows.Window.aspx )


 


function Get-MSDNInfo([Type]$t) { (New-Object –com Shell.Application).Open(“http://msdn.microsoft.com/$(Get-Culture)/library/$($t.FullName).aspx” ) }


 


# Create a new instance of an object and displays member info with Out-GridView, so you can search the information to find a property that might do what you want


function Show-ClassInfo([Type]$t) { Get-Member –input (New-Object $t.FullName $args) | Out-Gridview}


 


With these commands, I can close a of the discoverability gap for WFP & all of .NET, much more quickly.


 


Now let’s walk through how we use these commands to find out what else is in WPF, and show some more quick WPF & PowerShell samples.


 


WPF is in the System.Windows namespace and subnamespaces, and all controls are inherited from [Windows.Controls.Control], so you can quickly find all of the loaded controls with this one liner:


 


Get-Type | Where-Object { $_.IsSubclassOf([Windows.Controls.Control])}


 


First, let’s find a label, so we can change the font size of the Hello World.


 


Get-Type | Where-Object { $_.IsSubclassOf([Windows.Controls.Control])} | Where-Object {$_.Name –eq “Label”} | Select FullName


 


FullName                                                                                                                        


——–                                                                                                                         


System.Windows.Controls.Label                                                                                                   


 


Now, let’s go open it in MSDN and create a gridview containing a label:


 


Get-MSDNInfo System.Windows.Controls.Label


Show-ClassInfo System.Windows.Controls.Label


 


The MSDN page gives you the details on everything that is just applicable to the label, but Get-Member gives you every property, method, and event the control has.


 


A quick scrolling down this list will give you an idea of just how big the iceberg is. The label alone has 246 methods, properties, and events.


 


Luckily for us, Out-Gridview has a search window.  Let’s use it to find the properties named Size.


 


There’s


 


An Event, SizeChanged


A method, Measure, which takes a Size type


A DesiredSize Property


A FontSize Property


A RenderSize Property


 


Obviously, FontSize is the one we want to use to make our Hello World a little larger and easier to read.


 


Now our HelloWorld is:


 


$window = New-Object Windows.Window


$window.Title = “Hello World”


$label = New-Object Windows.Controls.Label


$label.Content, $label.FontSize = “Hello World”, 24


$window.Content = $label


$window.SizeToContent = “WidthAndHeight”


$null = $window.ShowDialog()


 


Let’s take a quick tour of some of the other really simple things we can do with WPF:


 


Create a Circle of a Random Size:


 


$window = New-Object Windows.Window


$color = (“Red”, “Green”,”Blue”,”Yellow” | Get-Random)


$window.Title = “See The Big $color Ball”


$circle = New-Object Windows.Shapes.Ellipse


      $circle.Width = $circle.Height = Get-Random –min 200 –max 450


      $circle.Fill = $color


      $window.Content = $circle


      $window.SizeToContent = “WidthAndHeight”


      $null = $window.ShowDialog()


 


Create an Ink Canvas the user can scribble on with the mouse or stylus


 


     $window = New-Object Windows.Window


     $window.Title = “Scribble on Me”


     $inkCanvas = New-Object Windows.Controls.InkCanvas


     $inkCanvas.MinWidth = $inkCanvas.MinHeight = 100


     $window.Content = $inkCanvas


     $window.SizeToContent = “WidthAndHeight”


     $null = $window.ShowDialog()


 


Show a slider, and get the value the slider was at after running:


 


$window = new-object Windows.Window


$slider = New-Object Windows.Controls.Slider


$slider.Maximum = 10


$slider.Minimum = 0


$window.Content = $slider


$window.SizeToContent = “WidthAndHeight”


$null = $window.ShowDialog()


      $slider.Value


 


Show a label and textbox, and emit the value the textbox contained:


 


$window = new-object Windows.Window


$stackPanel = new-object Windows.Controls.StackPanel


$text = New-Object Windows.Controls.TextBox


$label = New-Object Windows.Controls.Label


$label.Content = “Type Something”


$stackPanel.Children.Add($label) 


$stackPanel.Children.Add($text)


      $window.Content = $stackPanel


$window.SizeToContent = “WidthAndHeight”


$null = $window.ShowDialog()


      $text.Text


 


This post should give you a better sample of what WPF Contains, and how to close the Discoverability Gap and learn how to script more.  Stay tuned to see more interactive WPF.


 


Hope this Helps,


James Brundage [MSFT]