Create a Listview and update the data from an already running ShowUI GUI

Aug 30, 2011 at 1:39 AM

Hi Guys, How can I do this ?

Create a LlistvIew with 3 columns and 3 rows, lets say :

Name       City         Age
Laerte       Marilia    41
Joao         Tupa       35
Maria        Marilia    32

and then I want to update the data from an already running ShowUI GUI by using a cmdlet in the console ( Scriptblock for example)

Thanks :)

 

Coordinator
Aug 30, 2011 at 3:05 AM

ListView -Name People -Items { 
   New-Object PSobject -Prop @{ Name="Laerte";  City="Marilia"; Age=41}
   New-Object PSObject -Prop @{ Name="Joao";    City="Tupa";    Age=35}
   New-Object PSobject -Prop @{ Name="Maria";  City="Marilia"; Age=32}
} -View {
   GridView -Columns {
      GridViewColumn -Header Name -DisplayMember { Binding Name }
      GridViewColumn -Header City -DisplayMember { Binding City }
      GridViewColumn -Header Age -DisplayMember { Binding Age }
   }
} -AsJob

## Time passes ...

Get-Job People | Update-WPFJob { 
   $People.Items.Add(( New-Object PSobject -Prop @{ Name="Joel"; City="Rochester"; Age=37} ))
}

Developer
Aug 30, 2011 at 3:29 AM

Laerte, this may work for you.

Jaykul, I get the error below. The ShowUI I have is from a diff trunk though.

ListView -Name People -Items { 
   New-Object PSobject -Prop @{ Name="Laerte";  City="Marilia"; Age=41}
   New-Object PSObject -Prop @{ Name="Joao";    City="Tupa";    Age=35}
   New-Object PSobject -Prop @{ Name="Maria";  City="Marilia"; Age=32}
} -View {
   GridView -Columns {
      GridViewColumn -Header Name -DisplayMember { Binding Name }
      GridViewColumn -Header City -DisplayMember { Binding City }
      GridViewColumn -Header Age -DisplayMember { Binding Age }
   }
} -AsJob


At the ISE cmdline
Get-Job People | Update-WPFJob { 
   $People.Items.Add(( New-Object PSobject -Prop @{ Name="Joel"; City="Rochester"; Age=37} ))
}
Exception calling "InvokeScriptInJob" with "3" argument(s): "You cannot call a method on a null-valued express
ion."
At C:\Users\finked\Documents\WindowsPowerShell\Modules\ShowUI\Update-WPFJob.ps1:54 char:43
+                     $job.InvokeScriptInJob <<<< ($realCommand, $null, $Asynchronously)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodTargetInvocation
 

Coordinator
Aug 30, 2011 at 3:58 AM

Oh, yeah ... we haven't made an August release!?

So, uhm, yeah, the fix to make $People be populated in Update-WPFJob hasn't been released yet.  You'll have to go through $Window:

Get-Job People | Update-WPFJob { 
   $Window.Content.Items.Add(( New-Object PSobject -Prop @{ Name="Joel"; City="Rochester"; Age=37} ))
}

Aug 30, 2011 at 11:07 AM
Edited Aug 30, 2011 at 4:41 PM

Doug, Jaykul..Thanks a lot. Works fine.  And If I want to update the age of Laerte to 38  displaying in red color ? Can do this ?

Coordinator
Aug 30, 2011 at 4:41 PM

Ok, but since I don't know off the top of my head how to refresh .Items ... lets start over with an ItemsSource (which is my preferred way of doing this anyway):

New-ListView -Name People -ItemsSource {
   ## Please excuse the ridiculous PowerShell syntax for constructing generic collections with its casting
   New-Object System.Collections.ObjectModel.ObservableCollection[PSObject](,([PSObject[]](&{
      New-Object PSObject -Prop @{ Name="Laerte";  City="Marilia"; Age=41}
      New-Object PSObject -Prop @{ Name="Joao";    City="Tupa";    Age=35}
      New-Object PSObject -Prop @{ Name="Maria";  City="Marilia";  Age=32}
   })))
} -View {
   New-GridView -Columns {
      New-GridViewColumn -Header Name -DisplayMember { Binding Name }
      New-GridViewColumn -Header City -DisplayMember { Binding City }
      New-GridViewColumn -Header Age -DisplayMember { Binding Age }
   }
} -AsJob

## Adding existing items is easy, we just need to get that ObservableCollection first
Get-Job People | Update-WPFJob { 
   ## Note: When you have an ItemsSource, you can't use .Items.Add anymore!
   $Window.Content.ItemsSource.Add(( New-Object PSobject -Prop @{ Name="Joel"; City="Rochester"; Age=37} ))
}

## Important: ObservableCollection ignores INotifyPropertyChanged, so 
## if you change existing items, you have to remember to refresh the view
Get-Job People | Update-WPFJob {
   $Window.Content.ItemsSource | Where { $_.Name -eq "Laerte" } | %{ $_.Age = 36 }
   
   ## Magic incantation to refresh a view (we should probably stick this somewhere in ShowUI)
   [System.Windows.Data.CollectionViewSource]::GetDefaultView( $Window.Content.ItemsSource ).Refresh()
}

## If you want to set styles on stuff, then you need to get the ListViewItem, not the actual item:
Get-Job People | Update-WPFJob {
   foreach($item in $Window.Content.ItemsSource) { 
      # Don't trust anyone over 35
      if($item.Age -gt 35) {
         $ViewItem = $Window.Content.ItemContainerGenerator.ContainerFromItem( $item )
         $ViewItem.Background = "Pink"
      }
   }
}

Aug 30, 2011 at 5:13 PM

BIG THANKS  Jaykul, now I can start to work !!!!