Channels ▼
RSS

Embedded Systems

Building GUI Applications in PowerShell


A Twitter GUI Application

This is a simple but full-blown WPF application interacting with the Twitter search API that uses ShowUI.

Compared with C# and XAML, there is much less to learn to use PowerShell and ShowUI. PowerShell allows a higher-level abstraction than system languages, enabling more rapid application development. ShowUI enables the same level of abstractions for creating WPF user interfaces.

The Code

Twenty-nine lines of PowerShell produce the WPF application shown in Figure 3.


Figure 3: The Twitter search app GUI written in PowerShell.

The Search-Twitter function returns an array of PowerShell objects with properties from the Twitter query. From that data, we extract the text of the tweet and the URL pointing to the Twitter user's profile image. If you look closely at the PowerShell code here, you'll see no loops at all. ShowUI supports WPF's data binding capabilities as well as its templating features.

Import-Module .\ShowUI
function Search-Twitter ($q) {
$wc = New-Object Net.Webclient
$url = http://search.twitter.com/search.rss?q=$q
    ([xml]$wc.downloadstring($url)).rss.channel.item | select *
}

$ws = @{
    WindowStartupLocation = "CenterScreen"
    Width = 500
    Height = 500
}

New-Window @ws -Show {
    ListBox -Background Black -ItemTemplate {
        Grid -Columns 55, 300 {
        Image -Column 0 -Name Image -Margin 5
        TextBlock -Column 1 -Name Title `
            -Margin 5 `
            -Foreground White `
            -TextWrapping Wrap
    } | ConvertTo-DataTemplate -Binding @{
            "Image.Source" = "image_link"
            "Title.Text" = "title"
    }
  } -ItemsSource (Search-Twitter PowerShell)
}

ShowUI uses a code-generation technique that wraps all the WPF presentation components and their parameters so they fit seamlessly into the PowerShell ecosystem. This code accesses five WPF controls: Window, ListBox, Grid, Image, and Text Block.

I set the results of the Twitter search to the ItemsSource property of the ListBox, and then let data binding take care of the rest. The ConvertTo-DataTemplate "reaches" into the data context of the control to find the image_link and title properties. To do the styling, I used the –ItemTemplate parameter and ConvertTo-DataTemplate function. –ItemTemplate takes a PowerShell script block, in which I defined a WPF Grid with two columns. The first column will hold an Image control, which shows the Twitter user's picture.

If you set the source of the Image control to a URL, the picture is automatically fetched and displayed. The second column holds the TextBlock where the actual tweet message is displayed.

Note that the WPF data-templating model provides you with great flexibility to define the presentation of your data. WPF controls have built-in functionality to support the customization of data presentation. They give you a very flexible and powerful solution to replace the visual appearance of a data item in a control like ListBox. ShowUI integrates with this styling functionality via the –ItemTemplate parameter and ConvertTo-DataTemplate function.

Finally, I pipe the Grid "construction" to the ConvertTo-DataTemplate function that ships with ShowUI. This is where the controls are bound to the Twitter results created in the DataContext parameter via the –binding parameter. If you inspect the raw data returned from Search-Twitter, you'll see that there are in fact two properties on every object, one named image_link and the other text. Running the script bubbles up all the data into the ListBox, which is hosted by the New-Window, and we get the neat Twitter application.

ShowUI Video Player

ShowUI ships with many good examples, and its developers have blogged and recorded videos demoing ShowUI in action. Definitely check out these links to the videos:

One more simple and powerful app that you can code is a GUI video player that supports drag and drop and runs as a standalone application with only a handful of script.

Import-Module ShowUI

New-Window -AllowDrop -On_Drop {
    $VideoPlayer.Source = @($_.Data.GetFileDropList())[0]
    $VideoPlayer.Play()
} -On_Loaded {
    $VideoPlayer.Source = Get-ChildItem -Path `
     "$env:Public\Videos\Sample Videos" -Filter *.wmv |

    Get-Random | Select-Object -ExpandProperty Fullname
    $VideoPlayer.Play()
} -On_Closing {
    $VideoPlayer.Stop()
} -Content {
    New-MediaElement -Name VideoPlayer -LoadedBehavior Manual
} -AsJob

New-Window creates a WPF window, then –AsJob runs the window as a background job. Launching this window from the PowerShell console runs this application without blocking the command line from doing more work. The window gets the video player embedded in the –Content parameter, and it is named VideoPlayer. ShowUI makes that name accessible as $VideoPlayer. You can see this name being used in the rest of the script for properties being set, Source, and methods being called, Play() and Stop().

The –AllowDrop parameter enables the window as a drop target. You can drag other videos to the surface and drop them, and they will play. The –On_Drop parameter wires up the drop event, reads and sets the file dropped to the video player, and plays it. The -On_Loaded event is called when the window initially loads and a random .wmv file is selected to be played. Finally, when the window is closed, the –On_Closing event is called, and Stop() terminates the playing video.

Notice how it takes more space to explain a ShowUI application than it does to write it!

Summary

GUIs are fundamentally gluing applications; they don't really create new functionality, but rather, they make connections between controls and the internal functions of an application. Scripting languages excel at gluing. ShowUI connects the underlying components of WPF and PowerShell to create an environment of exceptional power. Using PowerShell this way is not limited to wrapping WPF and GUI components. However, with this approach, you can develop applications five to ten times faster.

PowerShell is not a replacement for a system programming language or vice versa. Each is suited to solve different problems. Finding that division of labor and combining their strengths leads to more rapid development and more flexible approaches. Enjoy!


Doug Finke is a Microsoft PowerShell MVP. He works in New York City for Lab49, a company that builds advanced applications for the financial services industry. This article was adapted and modified from Doug Finke's book Windows PowerShell for Developers.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video