tying a comobox to a datacontext

Oct 6, 2011 at 5:26 PM

I'd like to be able to filter in my WPF listview just like the out-gridview; the list of filter values available are pulled from the column that I last clicked on.  I wrote the Windows explorer-like code below to demonstrate the problem (I'm not really tyring to re-write Win Explorer but this code illustrates my problems).  The columns are sortable so the active column has been established.  I used a combobox for the filter and it works great - for a single property.  I want the -items in my combo box to be tied to the $sort variable which means I need to attach a datacontext to it that gets refreshed at the same time the $FileAndDirListView.datacontext gets changed. 

Lastly, I've got the same problem with the "CurrentLoc" label.  It also needs to be changed whenever the $FileAndDirListView.datacontext gets changed.  Can't quite figure it out.  Thanks for any help!

 

import-module showui
$global:backstack=new-object system.collections.Stack
$script:dir="c:\"

Function main($script:dir,$window,$backbutton=$false)
{
    if($script:dir -eq $null){$script:dir="c:\"}
    $global:mydir=$script:dir
   
    write-host "dir=$script:dir"
   
    if($script:dir -eq "back" -or (gi $script:dir).psiscontainer)
    {
        if($script:dir -eq "back"){$script:dir=$global:backstack.pop();$script:dir=$global:backstack.pop()}
        write-host "pushing $script:dir into backstack";$global:backstack.push($script:dir)      
      
        $FileAndDirListView=$window | Get-ChildControl -ByControlName "FileAndDir"
        $script:dirdata=(gci $script:dir | %{if($_.psiscontainer){$_ | select-object *,type | %{$_.type="D";$_}}
            else{$_ | select-object *,type | %{$_.type="F";$_}}})
           
        $FileAndDirListView.datacontext = $script:dirdata
    }
}   

Function Set-Filter($key,$window)
{
    $FileAndDirListView=$window | Get-ChildControl -ByControlName "FileAndDir"
    if($key -eq "No Filter"){ $FileAndDirListView.datacontext = $script:dirdata}
    else
    {
        $global:tempdata=@() #must be a collection
        $global:tempdata=($script:dirdata | where {$_.type -eq $key})
        if($global:tempdata -is [array]){$FileAndDirListView.datacontext = $global:tempdata}
        else{$FileAndDirListView.datacontext = ,$global:tempdata}
    }
    write-host "Key=$key"
}


New-Window -Title "Windows EXplorer" -WindowStartupLocation CenterScreen -Width 1000 -Height 600 `
{
    New-GRid -Rows 50,525 -columns 800*  `
    {
        New-Grid -Row 0 -columns 267,267,267 -rows 800* `
        {
            New-Button "Back"  -row 0 -column 0 -width 75 -height 35 -margin 5 -on_click {main "back" $window}
            New-Label -row 0 -column 1 -content $script:dir -controlname "CurrentLoc"
            New-ComboBox -row 0 -column 2 -width 150 -height 35 -items {($script:dirdata | sort -p type -unique | select -expandproperty type) + "No Filter"} -On_SelectionChanged {set-filter $this.selecteditem $window}
        }
       
        New-ListView -row 1 -controlname "FileAndDir" -DataBinding @{ItemsSource = New-Binding} -name MySelectedItems -View `
        {
                New-GridView -AllowsColumnReorder  -Columns `
                {
                    New-GridViewColumn 'type'
                    New-GridViewColumn 'FullName'
                    New-GridViewColumn 'CreationTime'
                    New-GridViewColumn 'LastAccessTime'
                    New-GridViewColumn 'Extension'                  
                }
        } -On_MouseDoubleClick {main ($this.selecteditems | select-object -expandproperty fullname ) $window
        } -On_Loaded {
                    main $null $window
                [System.Windows.RoutedEventHandler]$EventHandler = {
                Initialize-EventHandler
                $ErrorActionPreference = 'stop'

                ###### START EVENT HANDLER
                      if($_.OriginalSource -and $_.OriginalSource.Role -ne "Padding")
                      {
                        ## We need to sort by a PROPERTY of the objects in the gridview, in our example, we can just use the path that we used for binding ...
                        $global:Sort = $_.OriginalSource.Column.DisplayMemberBinding.Path.Path
                        $script:direction = if($global:Sort -eq $lastSort){if($lastDirection -eq "Descending"){"Ascending"} else { "Descending" }} else {"Ascending"}
                        $lastSort = $global:Sort
                        $lastDirection = $script:direction
                        #$global:a=$MySelectedItems.ItemsSource
                        $view = [System.Windows.Data.CollectionViewSource]::GetDefaultView( ($MySelectedItems.ItemsSource))
               Write-host "Sort: $global:Sort ($script:direction)"
                        $view.SortDescriptions.Clear()
                        $view.SortDescriptions.Add(( New-Object System.ComponentModel.SortDescription $global:Sort, $script:direction ))
                        $view.SortDescriptions.Add(( New-Object System.ComponentModel.SortDescription 'Start Date', "Ascending" ))
                        $view.Refresh()
                      } #if
                ###### END EVENT HANDLER
  
                trap {                       
                . Write-WPFError $_
                continue
                }
                } #eventhandler

                ## Hook up to a RoutedEvent from the grid headers by handling it on the ListView
                $MySelectedItems.AddHandler( [System.Windows.Controls.GridViewColumnHeader]::ClickEvent, $EventHandler)

           
                   } #on_load
                                      
    } #new-grid         
   
} -Show #new-window