Fixed a UI issue where sorting after filtering Drivers was causing the filter to break and all items were sorted instead of the filtered items.

This commit is contained in:
rbalsleyMSFT
2025-10-27 16:40:29 -07:00
parent 7598ee96da
commit b4305a1edb
@@ -505,21 +505,29 @@ function Invoke-ListViewSort {
[PSCustomObject]$State [PSCustomObject]$State
) )
# Preserve any active CollectionView filter so sorting does not reset a filtered driver model list
$existingFilter = $null
$existingCollectionView = $null
if ($null -ne $listView.ItemsSource) {
$existingCollectionView = [System.Windows.Data.CollectionViewSource]::GetDefaultView($listView.ItemsSource)
if ($null -ne $existingCollectionView -and $existingCollectionView.Filter) {
$existingFilter = $existingCollectionView.Filter
}
}
# Ensure $State.Flags is a hashtable and contains the required sort properties # Ensure $State.Flags is a hashtable and contains the required sort properties
if ($State.Flags -is [hashtable]) { if ($State.Flags -is [hashtable]) {
if (-not $State.Flags.ContainsKey('lastSortProperty')) { if (-not $State.Flags.ContainsKey('lastSortProperty')) {
$State.Flags['lastSortProperty'] = $null $State.Flags['lastSortProperty'] = $null
} }
if (-not $State.Flags.ContainsKey('lastSortAscending')) { if (-not $State.Flags.ContainsKey('lastSortAscending')) {
$State.Flags['lastSortAscending'] = $true # Default to ascending $State.Flags['lastSortAscending'] = $true
} }
} }
else { else {
Write-Warning "Invoke-ListViewSort: \$State.Flags is not a hashtable or is null. Sort state may not work correctly." Write-Warning "Invoke-ListViewSort: \$State.Flags is not a hashtable or is null. Sort state may not work correctly."
# Attempt to initialize if $State.Flags is null or unexpectedly not a hashtable,
# though this might indicate a deeper issue with $State.Flags initialization.
if ($null -eq $State.Flags) { $State.Flags = @{} } if ($null -eq $State.Flags) { $State.Flags = @{} }
if ($State.Flags -is [hashtable]) { # Check again after potential initialization if ($State.Flags -is [hashtable]) {
if (-not $State.Flags.ContainsKey('lastSortProperty')) { $State.Flags['lastSortProperty'] = $null } if (-not $State.Flags.ContainsKey('lastSortProperty')) { $State.Flags['lastSortProperty'] = $null }
if (-not $State.Flags.ContainsKey('lastSortAscending')) { $State.Flags['lastSortAscending'] = $true } if (-not $State.Flags.ContainsKey('lastSortAscending')) { $State.Flags['lastSortAscending'] = $true }
} }
@@ -534,10 +542,15 @@ function Invoke-ListViewSort {
} }
$State.Flags.lastSortProperty = $property $State.Flags.lastSortProperty = $property
# Get items from ItemsSource or Items collection # Build the set of items to sort, enumerating the filtered view if a filter is active
$currentItemsSource = $listView.ItemsSource $currentItemsSource = $listView.ItemsSource
$itemsToSort = @() $itemsToSort = @()
if ($null -ne $currentItemsSource) { if ($null -ne $existingCollectionView -and $null -ne $existingFilter) {
foreach ($vItem in $existingCollectionView) {
$itemsToSort += $vItem
}
}
elseif ($null -ne $currentItemsSource) {
$itemsToSort = @($currentItemsSource) $itemsToSort = @($currentItemsSource)
} }
else { else {
@@ -548,16 +561,17 @@ function Invoke-ListViewSort {
return return
} }
# Separate selected vs unselected for selected-first ordering
$selectedItems = @($itemsToSort | Where-Object { $_.IsSelected }) $selectedItems = @($itemsToSort | Where-Object { $_.IsSelected })
$unselectedItems = @($itemsToSort | Where-Object { -not $_.IsSelected }) $unselectedItems = @($itemsToSort | Where-Object { -not $_.IsSelected })
# Define the primary sort criterion # Define primary sort criterion
$primarySortDefinition = @{ $primarySortDefinition = @{
Expression = { Expression = {
$val = $_.$property $val = $_.$property
if ($null -eq $val) { '' } else { $val } if ($null -eq $val) { '' } else { $val }
} }
Ascending = $State.Flags.lastSortAscending Ascending = $State.Flags.lastSortAscending
} }
$sortCriteria = [System.Collections.Generic.List[hashtable]]::new() $sortCriteria = [System.Collections.Generic.List[hashtable]]::new()
@@ -579,11 +593,11 @@ function Invoke-ListViewSort {
$secondarySortPropertyName = "Key" $secondarySortPropertyName = "Key"
} }
else { else {
# Default secondary sort for IsSelected or other properties
$secondarySortPropertyName = "Key" $secondarySortPropertyName = "Key"
} }
} }
# Add secondary sort definition if applicable
if ($null -ne $secondarySortPropertyName -and $property -ne $secondarySortPropertyName) { if ($null -ne $secondarySortPropertyName -and $property -ne $secondarySortPropertyName) {
$itemsHaveSecondaryProperty = $false $itemsHaveSecondaryProperty = $false
if ($unselectedItems.Count -gt 0) { if ($unselectedItems.Count -gt 0) {
@@ -598,35 +612,40 @@ function Invoke-ListViewSort {
} }
if ($itemsHaveSecondaryProperty) { if ($itemsHaveSecondaryProperty) {
# Create a scriptblock for the secondary sort expression dynamically
$expressionScriptBlock = [scriptblock]::Create("`$_.$secondarySortPropertyName") $expressionScriptBlock = [scriptblock]::Create("`$_.$secondarySortPropertyName")
$secondarySortDefinition = @{ $secondarySortDefinition = @{
Expression = { Expression = {
$val = Invoke-Command -ScriptBlock $expressionScriptBlock -ArgumentList $_ $val = Invoke-Command -ScriptBlock $expressionScriptBlock -ArgumentList $_
if ($null -eq $val) { '' } else { $val } if ($null -eq $val) { '' } else { $val }
} }
Ascending = $true # Secondary sort always ascending Ascending = $true
} }
$sortCriteria.Add($secondarySortDefinition) $sortCriteria.Add($secondarySortDefinition)
} }
} }
# Sort unselected items by combined sort criteria
$sortedUnselected = $unselectedItems | Sort-Object -Property $sortCriteria.ToArray() $sortedUnselected = $unselectedItems | Sort-Object -Property $sortCriteria.ToArray()
# Ensure $sortedUnselected is not null before attempting to add its range
if ($null -eq $sortedUnselected) { if ($null -eq $sortedUnselected) {
$sortedUnselected = @() $sortedUnselected = @()
} }
# Combine sorted items: selected items first, then sorted unselected items # Merge selected first, then sorted unselected
$newSortedList = [System.Collections.Generic.List[object]]::new() $newSortedList = [System.Collections.Generic.List[object]]::new()
$newSortedList.AddRange($selectedItems) $newSortedList.AddRange($selectedItems)
$newSortedList.AddRange($sortedUnselected) $newSortedList.AddRange($sortedUnselected)
# Set the new sorted list as the ItemsSource # Reset ItemsSource and assign sorted list
# Try nulling out ItemsSource first to force a more complete refresh
$listView.ItemsSource = $null $listView.ItemsSource = $null
$listView.ItemsSource = $newSortedList.ToArray() $listView.ItemsSource = $newSortedList.ToArray()
# Reapply preserved filter to maintain the user's filtered view
if ($null -ne $existingFilter) {
$newView = [System.Windows.Data.CollectionViewSource]::GetDefaultView($listView.ItemsSource)
if ($null -ne $newView) {
$newView.Filter = $existingFilter
}
}
} }
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------