functions/New-WPFMessageBox.ps1

# display WPF equivalent of the VBSCriptMessageBox


#todo: dynamic parameter to set button default?

Function New-WPFMessageBox {

    [cmdletbinding(DefaultParameterSetName = "standard")]
    [alias("nmb")]
    [Outputtype([int], [boolean], [string])]

    Param(
        [Parameter(Position = 0, Mandatory, HelpMessage = "Enter the text message to display.")]
        [string]$Message,
        [string]$Title = "Message",
        [ValidateSet("Information", "Warning", "Error", "Question", "Shield")]
        [string]$Icon = "Information",
        [Parameter(ParameterSetName = "standard")]
        [ValidateSet("OK", "OKCancel", "YesNo")]
        [string]$ButtonSet = "OK",
        [Parameter(ParameterSetName = "custom")]
        [System.Collections.Specialized.OrderedDictionary]$CustomButtonSet,
        [string]$Background,
        [switch]$Quiet
    )

    if ($PSEdition -eq 'Core') {
        Write-Warning "Sorry. This command will not run on PowerShell Core."
        #bail out
        Return
    }

    # It may not be necessary to add these types but it doesn't hurt to include them
    # but if they can't be laoded then this function will never work anwyway
    Try {

        Add-Type -AssemblyName PresentationFramework -ErrorAction stop
        Add-Type -assemblyName PresentationCore -ErrorAction stop
        Add-Type -AssemblyName WindowsBase -ErrorAction stop
    }
    Catch {
        Throw $_
        #make sure we abort
        return
    }
    $form = New-Object System.Windows.Window
    #define what it looks like
    $form.Title = $Title
    $form.Height = 200
    $form.Width = 300
    $form.WindowStartupLocation = [System.Windows.WindowStartupLocation]::CenterScreen

    if ($Background) {
        Try {
            $form.Background = $Background
        }
        Catch {
            Write-Warning "See https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.brushes?view=netframework-4.7.2 for help on selecting a proper color. You can enter a color by name or X11 color value."
            Throw $_
        }
    }

    $grid = New-Object System.Windows.Controls.Grid

    $img = New-Object System.Windows.Controls.Image
    $img.Source = Join-Path "$psscriptroot\icons" -ChildPath "$icon.png"
    $img.Width = 50
    $img.Height = 50
    $img.HorizontalAlignment = "left"
    $img.VerticalAlignment = "top"
    $img.Margin = "15,5,0,0"

    $grid.AddChild($img)

    $text = New-Object System.Windows.Controls.Textblock
    $text.text = $Message
    $text.Padding = 10
    $text.Width = 200
    $text.Height = 80
    $text.Margin = "75,5,0,0"
    $text.TextWrapping = [System.Windows.TextWrapping]::Wrap
    $text.VerticalAlignment = "top"

    $text.HorizontalAlignment = "left"
    $grid.AddChild($text)

    if ($PSCmdlet.ParameterSetName -eq 'standard') {

        Switch ($ButtonSet) {

            "OK" {
                $btn = New-Object System.Windows.Controls.Button
                $btn.Content = "_OK"
                $btn.Width = 75
                $btn.Height = 25
                $btn.Margin = "0,80,0,0"
                $btn.Add_click( {
                        $form.close()
                        $script:r = 1
                    })
                $grid.AddChild($btn)
                $form.add_Loaded( {$btn.Focus()})
            } #ok
            "OKCancel" {
                $btnOK = New-Object System.Windows.Controls.Button
                $btnOK.Content = "_OK"
                $btnOK.Width = 75
                $btnOK.Height = 25

                $btnOK.Margin = "-75,75,0,0"
                $btnOK.Add_click( {
                        $form.close()
                        $script:r = 1
                    })
                $btnCan = New-Object System.Windows.Controls.Button
                $btnCan.Content = "_Cancel"
                $btnCan.Width = 75
                $btnCan.Height = 25
                $btnCan.Margin = "120,75,0,0"
                $btnCan.Add_click( {
                        $form.close()
                        $script:r = 0
                    })
                $grid.AddChild($btnOK)
                $grid.AddChild($btnCan)
                $form.add_Loaded( { $btnOK.Focus()})
            } #okcancel
            "YesNo" {
                $btnY = New-Object System.Windows.Controls.Button
                $btnY.Content = "_Yes"
                $btnY.Width = 75
                $btnY.Height = 25
                $btnY.Margin = "-75,75,0,0"
                $btnY.Add_click( {
                        $form.close()
                        $script:r = $True
                    })
                $btnNo = New-Object System.Windows.Controls.Button
                $btnNo.Content = "_No"
                $btnNo.Width = 75
                $btnNo.Height = 25
                $btnNo.Margin = "120,75,0,0"
                $btnNo.Add_click( {
                        $form.close()
                        $script:r = $False
                    })
                $grid.AddChild($btnY)
                $grid.AddChild($btnNo)
                $form.add_Loaded( {$btnY.Focus()})
            } #yesno
        }
    }
    else {
        #create a custom set of buttons from the hashtable
        switch ($CustomButtonSet.keys.count) {
            1 {
                $btn = New-Object System.Windows.Controls.Button
                $btn.Content = "_$($customButtonSet.keys[0])"
                $btn.Width = 75
                $btn.Height = 25
                $btn.Margin = "0,80,0,0"
                $btn.Add_click( {
                        $form.close()
                        $script:r = $customButtonSet.values[0]
                    })
                $grid.AddChild($btn)
                $form.add_Loaded( {$btn.Focus()})
            }
            2 {
                $btn1 = New-Object System.Windows.Controls.Button
                $btn1.Content = "_$($customButtonSet.GetEnumerator().name[0])"
                $btn1.Width = 75
                $btn1.Height = 25
                $btn1.Margin = "-75,75,0,0"
                $btn1.Add_click( {
                        $form.close()
                        $script:r = $customButtonSet[0]
                    })
                $btn2 = New-Object System.Windows.Controls.Button
                $btn2.Content = "_$($customButtonSet.GetEnumerator().name[1])"
                $btn2.Width = 75
                $btn2.Height = 25
                $btn2.Margin = "120,75,0,0"
                $btn2.Add_click( {
                        $form.close()
                        $script:r = $customButtonSet[1]
                    })
                $grid.AddChild($btn1)
                $grid.AddChild($btn2)
                $form.add_Loaded( {$btn1.Focus()})
            }
            3 {
                $btn1 = New-Object System.Windows.Controls.Button
                $btn1.Content = "_$($customButtonSet.GetEnumerator().name[0])"
                $btn1.Width = 75
                $btn1.Height = 25
                $btn1.Margin = "-175,75,0,0"
                $btn1.Add_click( {
                        $form.close()
                        $script:r = $customButtonSet[0]
                    })
                $btn2 = New-Object System.Windows.Controls.Button
                $btn2.Content = "_$($customButtonSet.GetEnumerator().name[1])"
                $btn2.Width = 75
                $btn2.Height = 25
                $btn2.Margin = "0,75,0,0"
                $btn2.Add_click( {
                        $form.close()
                        $script:r = $customButtonSet[1]
                    })
                $btn3 = New-Object System.Windows.Controls.Button
                $btn3.Content = "_$($customButtonSet.GetEnumerator().name[2])"
                $btn3.Width = 75
                $btn3.Height = 25
                $btn3.Margin = "175,75,0,0"
                $btn3.Add_click( {
                        $form.close()
                        $script:r = $customButtonSet[2]
                    })
                $grid.AddChild($btn1)
                $grid.AddChild($btn2)
                $grid.AddChild($btn3)
                $form.add_Loaded( {$btn1.Focus()})
            }
            Default {
                Write-Warning "The form cannot accomodate more than 3 buttons."
                #bail out
                Return
            }
        }
    }

    #display the form
    $form.AddChild($grid)
    $form.ShowDialog() | Out-Null

    #write the button result to the pipeline if not using -Quiet
    if (-Not $Quiet) {
        $script:r
    }

} #end function