@@ -22,7 +22,15 @@ internal class ConsoleGui : IDisposable
22
22
private Label _filterLabel ;
23
23
private TextField _filterField ;
24
24
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 ;
26
34
private ApplicationData _applicationData ;
27
35
private GridViewDetails _gridViewDetails ;
28
36
@@ -43,8 +51,9 @@ public HashSet<int> Start(ApplicationData applicationData)
43
51
List < string > gridHeaders = _applicationData . DataTable . DataColumns . Select ( ( c ) => c . Label ) . ToList ( ) ;
44
52
CalculateColumnWidths ( gridHeaders ) ;
45
53
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 ( ) ;
48
57
49
58
if ( ! _applicationData . MinUI )
50
59
{
@@ -60,7 +69,9 @@ public HashSet<int> Start(ApplicationData applicationData)
60
69
// Status bar is where our key-bindings are handled
61
70
AddStatusBar ( ! _applicationData . MinUI ) ;
62
71
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.
64
75
ApplyFilter ( ) ;
65
76
66
77
_listView . SetFocus ( ) ;
@@ -76,10 +87,8 @@ public HashSet<int> Start(ApplicationData applicationData)
76
87
return selectedIndexes ;
77
88
}
78
89
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 )
83
92
{
84
93
if ( gvr . IsMarked )
85
94
{
@@ -109,6 +118,7 @@ private GridViewDataSource LoadData()
109
118
items . Add ( new GridViewRow
110
119
{
111
120
DisplayString = displayString ,
121
+ // We use this to keep _inputSource up to date when a filter is applied
112
122
OriginalIndex = i
113
123
} ) ;
114
124
@@ -120,9 +130,22 @@ private GridViewDataSource LoadData()
120
130
121
131
private void ApplyFilter ( )
122
132
{
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 ;
126
149
}
127
150
128
151
private void Accept ( )
@@ -198,7 +221,7 @@ private void AddStatusBar(bool visible)
198
221
// when ENTER is pressed in Single mode. If something was previously selected
199
222
// (using SPACE) then honor that as the single item to return
200
223
if ( _applicationData . OutputMode == OutputModeOption . Single &&
201
- _itemSource . GridViewRowList . Find ( i => i . IsMarked ) == null )
224
+ _inputSource . GridViewRowList . Find ( i => i . IsMarked ) == null )
202
225
{
203
226
_listView . MarkUnmarkRow ( ) ;
204
227
}
@@ -315,7 +338,7 @@ private void AddFilter(Window win)
315
338
filterErrorLabel . Text = ex . Message ;
316
339
filterErrorLabel . ColorScheme = Colors . Error ;
317
340
filterErrorLabel . Redraw ( filterErrorLabel . Bounds ) ;
318
- _listView . Source = _itemSource ;
341
+ _listView . Source = _inputSource ;
319
342
}
320
343
} ;
321
344
@@ -370,7 +393,7 @@ private void AddHeaders(Window win, List<string> gridHeaders)
370
393
371
394
private void AddListView ( Window win )
372
395
{
373
- _listView = new ListView ( _itemSource ) ;
396
+ _listView = new ListView ( _inputSource ) ;
374
397
_listView . X = MARGIN_LEFT ;
375
398
if ( ! _applicationData . MinUI )
376
399
{
0 commit comments