1

So I am writing a WPF window with powershell using this code

Add-Type -AssemblyName PresentationFramework
class Window 
{
    [System.Windows.Window]$window
    [System.Windows.Controls.Button]$button
    [int]$count = 0

    Window()
    {
        [xml]$xaml = @"
        <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            x:Name="Window"
            Title="C#Shell!">
            <Grid x:Name="Grid">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="100"/>
                </Grid.RowDefinitions>
                
                <ListView x:Name="List" />
                <Button x:Name="AddButton" Content="Add" Grid.Row="1"/>
            </Grid>
        </Window>
"@
        $reader = [System.Xml.XmlNodeReader]::new($xaml)
        $this.window = [System.Windows.Markup.XamlReader]::Load($reader)
        $this.button = $this.window.FindName("AddButton")
        $this.button.Add_Click({
            # How do I access this.window??
            $this.window.FindName("List").Items.Add("Item" + ($this.count++).ToString())
        })
        $this.window.ShowDialog()
    }
}

$window = [Window]::new()

How can I access this.window inside that Add_Click script block? This current code gives me

Exception calling "ShowDialog" with "0" argument(s): "You cannot call a method on a null-valued expression."
At line:33 char:9

And I can tell it's not because of ShowDialog(). That line should have been executed, otherwise there will be no window.

0

1 Answer 1

1

Not a great idea to use PowerShell classes for GUI apps, in the context of the System.Windows.Window event handlers, $this is an automatic variable that represents the sender and $_ is an automatic variable that represents the event args. Because of this you lose the reference to the instance containing it.

$this.button.Add_Click({
    param($s, $e)

    # `$s` the sender, is the same as `$this`
    $s -eq $this | Out-Host
    # `$e` the event args, is the same as `$_`
    $e -eq $_ | Out-Host
})

You could for example use $this.Parent.Parent to get to the parent System.Windows.Window, but to reference back the instance of your type you will most likely have to use Get-Variable with -Scope 1 (1 for the parent scope of the handler):

$this.button.Add_Click({
    [Window] $window = Get-Variable this -Scope 1 -ValueOnly -EA 0
    $window.window.FindName('List').Items.Add('Item' + ($window.count++).ToString())
})
Sign up to request clarification or add additional context in comments.

1 Comment

np.. @mklement0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.