Inject Dynamic WPF GUIs into your PowerShell Pipeline

by Doug Finke on August 15, 2009

in C#,C# 3.0,PowerBoots,PowerShell,WPF

This post provides a PowerShell script with the Function Edit-Object. Edit-Object takes an object, discovers the properties and displays the name and value for editing in a WPF form.

Edit-Object GUI

Below, the Person object has 6 properties Name, Age, Address, City, State, Zip.

Edit-Object (New-Object Person("John Doe", 5,"Somewhere in the US","Common Town","State","00000") )
             

Edit-Object builds the GUI on the fly from the properties and presents their values for editing.

image

Pressing Ok cycles through the textbox controls and sets the values back into the objects properties. Returning the object to the PowerShell pipeline for processing.

Pressing Cancel or Escape closes the window and returns nothing.

Works with C# Objects

The code below creates the form we just saw. It compiles a C#Version3 program in PowerShell using Add-Type. Then renders a WPF edit form with Edit-Object.

Add-Type @"
public class Person {
    public string Name { get; set; }
    public int    Age  { get; set; }

    public string Address { get; set; }
    public string City    { get; set; }
    public string State   { get; set; }
    public string Zip     { get; set; }

    public Person(string name, int age, string address, string city, string state, string zip) {
        this.Name = name;
        this.Age = age;
        this.Address = address;
        this.City = city;
        this.State = state;
        this.Zip = zip;
    }

}
"@ -Language CSharpVersion3            

Edit-Object (New-Object Person("John Doe", 5,"Somewhere in the US","Common Town","State","00000") )
             

Edit-Object Code

Edit-Object depends on PowerBoots. Grab the Edit-Object Code at the end of the post.

Function Edit-Object ($targetObject) {
    Function Generate-RowDefinitions ($n) { 0..($n+1) | %{ RowDefinition -Height Auto } }            

    Function Generate-Content ($o, $p) {
        $p | %{$rc=0} {
            Label -Content $_.Name -"Grid.Column" 0 -"Grid.Row" $rc
            TextBox -Text $o.($_.Name) -"Grid.Column" 1 -"Grid.Row" $rc -Name $_.Name -Margin 2
            $rc++
        }
    }            

    $global:obj = $targetObject
    $global:properties = $global:obj.psobject.properties | ?{ $_.issettable }            

    $global:cd = (ColumnDefinition 100), (ColumnDefinition Auto)
    $global:rd = Generate-RowDefinitions $properties.Count            

    $global:content  = Generate-Content $obj $properties
    $global:OkClicked = $false            

    Boots -Title 'Edit Object' -WindowStartupLocation CenterScreen {
        StackPanel {
            GridPanel -RowDefinitions @($global:rd) -ColumnDefinitions @($global:cd) {
                $global:content
            }               

            StackPanel -Orientation Horizontal {
                Button -Content '_Ok' -Margin 7 -Width 75 -On_Click {
                    $global:properties | %{
                        $global:obj.($_.name) = (Select-BootsElement $bootswindow  $_.name).Text
                    }            

                    $global:OkClicked = $true
                    $bootswindow.Close()
                }            

                Button -Content '_Cancel' -Margin 7 -Width 75 -IsCancel -On_Click {
                    $bootswindow.Close()
                }
            }
        }
    }            

    if($global:OkClicked) { $global:obj }
}

Thanks

To Joel ‘Jaykul’ Bennett for creating PowerBoots and Oisin Grehan for providing guidance on how to discover the read/write properties of an object in PowerShell.

Grab the Code

{ 3 trackbacks }

3 More Ways To Inject Dynamic WPF GUIs into your PowerShell Pipeline
08.17.09 at 8:40 am
Update: Dynamic GUIs and the PowerShell Pipeline
08.29.09 at 8:21 am
PowerShell Hacker #13
08.27.10 at 6:42 pm

{ 0 comments… add one now }

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>