What is the best way to auto-refresh ListView ItemsSource?

Aug 30, 2011 at 9:44 AM

Taking the following code as an example:

#Import-Module ShowUI
New-Grid -Name ServiceManager -Rows Auto,1*,Auto {
    New-StackPanel -Orientation Horizontal {
        "Computer Name"
        New-TextBox -Name computerName -Width 100 -Text "localhost" -Margin 5
        New-Button "Connect" -Width 100 -On_Click {
            $serviceList.ItemsSource = @(Get-Service -ComputerName $computerName.Text)
        }
    }    
    New-ListView -Row 1 -Name ServiceList -MaxHeight 500 -View {
        New-GridView -Columns {
            New-GridViewColumn -Header Name -DisplayMemberBinding Name
            New-GridViewColumn Status
            New-GridViewColumn DisplayName
        }
    } -On_SelectionChanged  {
        $Toggle.IsEnabled = $true
    }
    New-StackPanel -Row 2 -Orientation Horizontal -HorizontalAlignment Center {
        New-Button -Name Toggle "Toggle State" -Width 100 -IsEnabled:$false -On_Click {
            Foreach ($item in $ServiceList.SelectedItems) {
                if ($item.Status -eq 'Running') {
                    (Get-WmiObject -computer $computerName.Text -Class Win32_Service -Filter "Name='$($item.Name)'").StopService()
                } else {
                    (Get-WmiObject -computer $computerName.Text -Class Win32_Service -Filter "Name='$($item.Name)'").StartService()
                }
            }
            $serviceList.ItemsSource = @(Get-Service -ComputerName $computerName.Text)
        }
        New-Button "Close" -IsCancel -Width 100
    }           
} -On_Load {
        $serviceList.ItemsSource = @(Get-Service -ComputerName $computerName.Text)
        $computerName.Focus()
} -show

I want to be able to refresh the ListView source to reflect the new service status. At the moment, I am resetting the ItemsSource. On a local machine this may work really well. But, with a remote system, this may be blocking and/or take long time to refresh. Is there a better way?

Coordinator
Aug 30, 2011 at 5:01 PM

[System.Windows.Data.CollectionViewSource]::GetDefaultView( $ServiceList.ItemsSource ).Refresh()

Aug 31, 2011 at 3:16 AM

This is not working in the button event handler. I have to manually retrieve the services again!

Coordinator
Aug 31, 2011 at 3:41 AM

Yeah, it turns out that the System.ServiceProcess.ServiceController objects don't update themselves. So if you do:

$s = Get-Service WinRM
$s.Status
Start-Service WinRM
$s.Status
Stop-Service WinRM
$s.Status

The status will be the same the whole time, so refreshing the view won't help, because the object itself isn't changed.

Aug 31, 2011 at 6:28 AM

Gotcha. Thanks again.

Ravi