@@ -22,7 +22,15 @@ internal class ConsoleGui : IDisposable
2222 private Label _filterLabel ;
2323 private TextField _filterField ;
2424 private ListView _listView ;
25- private GridViewDataSource _itemSource ;
25+ // _inputSource contains the full set of Input data and tracks any items the user
26+ // marks. When the cmdlet exits, any marked items are returned. When a filter is
27+ // active, the list view shows a copy of _inputSource that includes both the items
28+ // matching the filter AND any items previously marked.
29+ private GridViewDataSource _inputSource ;
30+
31+ // _listViewSource is a filtered copy of _inputSource that ListView.Source is set to.
32+ // Changes to IsMarked are propogated back to _inputSource.
33+ private GridViewDataSource _listViewSource ;
2634 private ApplicationData _applicationData ;
2735 private GridViewDetails _gridViewDetails ;
2836
@@ -43,8 +51,9 @@ public HashSet<int> Start(ApplicationData applicationData)
4351 List < string > gridHeaders = _applicationData . DataTable . DataColumns . Select ( ( c ) => c . Label ) . ToList ( ) ;
4452 CalculateColumnWidths ( gridHeaders ) ;
4553
46- // Copy DataTable into the ListView's DataSource
47- _itemSource = LoadData ( ) ;
54+ // Copy the input DataTable into our master ListView source list; upon exit any items
55+ // that are IsMarked are returned (if Outputmode is set)
56+ _inputSource = LoadData ( ) ;
4857
4958 if ( ! _applicationData . MinUI )
5059 {
@@ -60,7 +69,9 @@ public HashSet<int> Start(ApplicationData applicationData)
6069 // Status bar is where our key-bindings are handled
6170 AddStatusBar ( ! _applicationData . MinUI ) ;
6271
63- // If -Filter parameter is set, apply it.
72+ // We *always* apply a filter, even if the -Filter parameter is not set or Filtering is not
73+ // available. The ListView always shows a fitlered version of _inputSource even if there is no
74+ // actual fitler.
6475 ApplyFilter ( ) ;
6576
6677 _listView . SetFocus ( ) ;
@@ -76,10 +87,8 @@ public HashSet<int> Start(ApplicationData applicationData)
7687 return selectedIndexes ;
7788 }
7889
79- // Ensure that only items that are marked AND not filtered out
80- // get returned (See Issue #121)
81- List < GridViewRow > itemList = GridViewHelpers . FilterData ( _itemSource . GridViewRowList , _applicationData . Filter ) ;
82- foreach ( GridViewRow gvr in itemList )
90+ // Return any items that were selected.
91+ foreach ( GridViewRow gvr in _inputSource . GridViewRowList )
8392 {
8493 if ( gvr . IsMarked )
8594 {
@@ -109,6 +118,7 @@ private GridViewDataSource LoadData()
109118 items . Add ( new GridViewRow
110119 {
111120 DisplayString = displayString ,
121+ // We use this to keep _inputSource up to date when a filter is applied
112122 OriginalIndex = i
113123 } ) ;
114124
@@ -120,9 +130,22 @@ private GridViewDataSource LoadData()
120130
121131 private void ApplyFilter ( )
122132 {
123- List < GridViewRow > itemList = GridViewHelpers . FilterData ( _itemSource . GridViewRowList , _applicationData . Filter ?? string . Empty ) ;
124- // Set the ListView to show only the subset defined by the filter
125- _listView . Source = new GridViewDataSource ( itemList ) ;
133+ // The ListView is always filled with a (filtered) copy of _inputSource.
134+ // We listen for `MarkChanged` events on this filtered list and apply those changes up to _inputSource.
135+
136+ if ( _listViewSource != null ) {
137+ _listViewSource . MarkChanged -= ListViewSource_MarkChanged ;
138+ _listViewSource = null ;
139+ }
140+
141+ _listViewSource = new GridViewDataSource ( GridViewHelpers . FilterData ( _inputSource . GridViewRowList , _applicationData . Filter ?? string . Empty ) ) ;
142+ _listViewSource . MarkChanged += ListViewSource_MarkChanged ;
143+ _listView . Source = _listViewSource ;
144+ }
145+
146+ private void ListViewSource_MarkChanged ( object s , GridViewDataSource . RowMarkedEventArgs a )
147+ {
148+ _inputSource . GridViewRowList [ a . Row . OriginalIndex ] . IsMarked = a . Row . IsMarked ;
126149 }
127150
128151 private void Accept ( )
@@ -198,7 +221,7 @@ private void AddStatusBar(bool visible)
198221 // when ENTER is pressed in Single mode. If something was previously selected
199222 // (using SPACE) then honor that as the single item to return
200223 if ( _applicationData . OutputMode == OutputModeOption . Single &&
201- _itemSource . GridViewRowList . Find ( i => i . IsMarked ) == null )
224+ _inputSource . GridViewRowList . Find ( i => i . IsMarked ) == null )
202225 {
203226 _listView . MarkUnmarkRow ( ) ;
204227 }
@@ -315,7 +338,7 @@ private void AddFilter(Window win)
315338 filterErrorLabel . Text = ex . Message ;
316339 filterErrorLabel . ColorScheme = Colors . Error ;
317340 filterErrorLabel . Redraw ( filterErrorLabel . Bounds ) ;
318- _listView . Source = _itemSource ;
341+ _listView . Source = _inputSource ;
319342 }
320343 } ;
321344
@@ -370,7 +393,7 @@ private void AddHeaders(Window win, List<string> gridHeaders)
370393
371394 private void AddListView ( Window win )
372395 {
373- _listView = new ListView ( _itemSource ) ;
396+ _listView = new ListView ( _inputSource ) ;
374397 _listView . X = MARGIN_LEFT ;
375398 if ( ! _applicationData . MinUI )
376399 {
0 commit comments