After looking over the scripts I’ve pasted in the last few days it struck me that all of them load the UI from XAML — and for the most part, you can do pretty much whatever you need to do in WPF in pure PowerShell if you want to.

Select-Grid ScreenshotTo demonstrate this, I wrote a simple Out-Grid script. But then I got carried away, and wrote the script I’ve shown in this screenshot. :-D The resulting script not only illustrates how to code WPF in PowerShell without XAML, it also illustrates one of the few areas where you’re much better off loading from XAML than writing the plain code — and that’s a DataTemplate. It is possible to write them in code, but believe it or not, some of their features are accessible only from XAML.

[new] I’ve updated both the script and the screenshot to correct a bug I noticed last night after I posted this … so if you tried this and got a lot more columns than you had bargained for … here is the Select-Grid script again. [new] I updated it again just now to switch my Set-PsDebug statement for a Set-StrictMode statement, after reading Jeffrey Snover’s post about strict mode best practices.

I’m not going to paste the whole script in-line, but I thought I’d paste some of it here so that I could give a little explanation of what’s happening, in case you need a little help figuring it out…

Using modules …

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

I will write a separate post about how PowerShell Modules work, and what you can do with them … it’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: Export-ModuleMember Select-Grid and rename it to [new] Select-Grid.psm1 and put it in a specific location: Documents\WindowsPowerShell\Packages\Select-Grid\Select-Grid.psm1 — but of course, I couldn’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 — look in the comment at the top).

Having done that, all you have to do is run Add-Module Select-Grid instead of dot-sourcing it, and then run it as before (see the screenshot).

Let’s talk about code bay-bee …

There’s a few things I wanted to point out in the module’s code, so lets get to that. (more…)

After posting my last post, I started thinking that perhaps I shouldn’t really have started with something so splashy [rolleyes]. So I started thinking about what I could use as a proper example — not of what WPF can do, but of what you might want to use WPF for in PowerShell.

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’t work with WinForms.

User Input prompts

I’ll write more about this in future posts, but for now, take as an ultimate example the latest post from mow, The PowerShell Guy in which he rewrites his PowerShell WMI Explorer to be WPF based — it seems to not only run faster, but be based on less code (of course, that might just be because he’s gained experience since the first version).

Data-bound Graphs

A WPF databound bar graph dialog from PowerShellThere are dozens of ways you can do data-bound graphs in PowerShell — including 3d — 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’ve written a simple graph window in XAML, and created a script Out-BarGraph which lets you send data to it … but there are, as the Genie says, some caveats, provisos, addendums, and quid pro quos. ;) (more…)

In my last post I wrote about how you could make a WPF Splash screen window in PowerShell, but I stated that: “if the images are remote, the WPF window has to download them, and therefore won’t work” correctly. I had played with downloading images directly by setting the Source attribute of the image to the image URL, and hadn’t been able to find a way to get the threading to work well enough to actually download the image.

Well, I figured that out, so I thought I’d go ahead and share … basically, all you have to do is call Invoke() on the window’s dispatcher. The reason that works is that WPF handles events and “work” 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.

This is PowerShell v2 CTP2 code…

All of this code is written to target the CTP2 release of PowerShell v2 — it will not work in PowerShell v1 or even in v2 CTP1 … and it may not work in later releases, although I expect it will. Also, as with any code which uses WPF from PowerShell, these code examples require you to launch PowerShell with the -STA option.

Having said that, lets just straight to a WPF example (more…)