@@ -32,8 +32,8 @@ public class ItemsSourceView : INotifyCollectionChanged, IDisposable
32
32
/// </summary>
33
33
public static ItemsSourceView Empty { get ; } = new ItemsSourceView ( Array . Empty < object > ( ) ) ;
34
34
35
- private protected readonly IList _inner ;
36
- private INotifyCollectionChanged ? _notifyCollectionChanged ;
35
+ private IList ? _inner ;
36
+ private NotifyCollectionChangedEventHandler ? _collectionChanged ;
37
37
38
38
/// <summary>
39
39
/// Initializes a new instance of the ItemsSourceView class for the specified data source.
@@ -42,27 +42,22 @@ public class ItemsSourceView : INotifyCollectionChanged, IDisposable
42
42
public ItemsSourceView ( IEnumerable source )
43
43
{
44
44
source = source ?? throw new ArgumentNullException ( nameof ( source ) ) ;
45
-
46
- if ( source is IList list )
47
- {
48
- _inner = list ;
49
- }
50
- else if ( source is IEnumerable < object > objectEnumerable )
45
+ _inner = source switch
51
46
{
52
- _inner = new List < object > ( objectEnumerable ) ;
53
- }
54
- else
55
- {
56
- _inner = new List < object > ( source . Cast < object > ( ) ) ;
57
- }
58
-
59
- ListenToCollectionChanges ( ) ;
47
+ ItemsSourceView _ => throw new ArgumentException ( "Cannot wrap an existing ItemsSourceView." , nameof ( source ) ) ,
48
+ IList list => list ,
49
+ INotifyCollectionChanged _ => throw new ArgumentException (
50
+ "Collection implements INotifyCollectionChanged by not IList." ,
51
+ nameof ( source ) ) ,
52
+ IEnumerable < object > iObj => new List < object > ( iObj ) ,
53
+ _ => new List < object > ( source . Cast < object > ( ) )
54
+ } ;
60
55
}
61
56
62
57
/// <summary>
63
58
/// Gets the number of items in the collection.
64
59
/// </summary>
65
- public int Count => _inner . Count ;
60
+ public int Count => Inner . Count ;
66
61
67
62
/// <summary>
68
63
/// Gets a value that indicates whether the items source can provide a unique key for each item.
@@ -72,6 +67,19 @@ public ItemsSourceView(IEnumerable source)
72
67
/// </remarks>
73
68
public bool HasKeyIndexMapping => false ;
74
69
70
+ /// <summary>
71
+ /// Gets the inner collection.
72
+ /// </summary>
73
+ public IList Inner
74
+ {
75
+ get
76
+ {
77
+ if ( _inner is null )
78
+ ThrowDisposed ( ) ;
79
+ return _inner ! ;
80
+ }
81
+ }
82
+
75
83
/// <summary>
76
84
/// Retrieves the item at the specified index.
77
85
/// </summary>
@@ -82,25 +90,48 @@ public ItemsSourceView(IEnumerable source)
82
90
/// <summary>
83
91
/// Occurs when the collection has changed to indicate the reason for the change and which items changed.
84
92
/// </summary>
85
- public event NotifyCollectionChangedEventHandler ? CollectionChanged ;
93
+ public event NotifyCollectionChangedEventHandler ? CollectionChanged
94
+ {
95
+ add
96
+ {
97
+ if ( _collectionChanged is null && Inner is INotifyCollectionChanged incc )
98
+ {
99
+ incc . CollectionChanged += OnCollectionChanged ;
100
+ }
101
+
102
+ _collectionChanged += value ;
103
+ }
104
+
105
+ remove
106
+ {
107
+ _collectionChanged -= value ;
108
+
109
+ if ( _collectionChanged is null && Inner is INotifyCollectionChanged incc )
110
+ {
111
+ incc . CollectionChanged -= OnCollectionChanged ;
112
+ }
113
+ }
114
+ }
86
115
87
116
/// <inheritdoc/>
88
117
public void Dispose ( )
89
118
{
90
- if ( _notifyCollectionChanged != null )
119
+ if ( _inner is INotifyCollectionChanged incc )
91
120
{
92
- _notifyCollectionChanged . CollectionChanged -= OnCollectionChanged ;
121
+ incc . CollectionChanged -= OnCollectionChanged ;
93
122
}
123
+
124
+ _inner = null ;
94
125
}
95
126
96
127
/// <summary>
97
128
/// Retrieves the item at the specified index.
98
129
/// </summary>
99
130
/// <param name="index">The index.</param>
100
131
/// <returns>The item.</returns>
101
- public object ? GetAt ( int index ) => _inner [ index ] ;
132
+ public object ? GetAt ( int index ) => Inner [ index ] ;
102
133
103
- public int IndexOf ( object ? item ) => _inner . IndexOf ( item ) ;
134
+ public int IndexOf ( object ? item ) => Inner . IndexOf ( item ) ;
104
135
105
136
public static ItemsSourceView GetOrCreate ( IEnumerable ? items )
106
137
{
@@ -146,38 +177,31 @@ public int IndexFromKey(string key)
146
177
147
178
internal void AddListener ( ICollectionChangedListener listener )
148
179
{
149
- if ( _inner is INotifyCollectionChanged incc )
180
+ if ( Inner is INotifyCollectionChanged incc )
150
181
{
151
182
CollectionChangedEventManager . Instance . AddListener ( incc , listener ) ;
152
183
}
153
184
}
154
185
155
186
internal void RemoveListener ( ICollectionChangedListener listener )
156
187
{
157
- if ( _inner is INotifyCollectionChanged incc )
188
+ if ( Inner is INotifyCollectionChanged incc )
158
189
{
159
190
CollectionChangedEventManager . Instance . RemoveListener ( incc , listener ) ;
160
191
}
161
192
}
162
193
163
194
protected void OnItemsSourceChanged ( NotifyCollectionChangedEventArgs args )
164
195
{
165
- CollectionChanged ? . Invoke ( this , args ) ;
166
- }
167
-
168
- private void ListenToCollectionChanges ( )
169
- {
170
- if ( _inner is INotifyCollectionChanged incc )
171
- {
172
- incc . CollectionChanged += OnCollectionChanged ;
173
- _notifyCollectionChanged = incc ;
174
- }
196
+ _collectionChanged ? . Invoke ( this , args ) ;
175
197
}
176
198
177
199
private void OnCollectionChanged ( object sender , NotifyCollectionChangedEventArgs e )
178
200
{
179
201
OnItemsSourceChanged ( e ) ;
180
202
}
203
+
204
+ private void ThrowDisposed ( ) => throw new ObjectDisposedException ( nameof ( ItemsSourceView ) ) ;
181
205
}
182
206
183
207
public class ItemsSourceView < T > : ItemsSourceView , IReadOnlyList < T >
@@ -216,10 +240,10 @@ private ItemsSourceView(IEnumerable source)
216
240
/// <param name="index">The index.</param>
217
241
/// <returns>The item.</returns>
218
242
[ return : MaybeNull ]
219
- public new T GetAt ( int index ) => ( T ) _inner [ index ] ;
243
+ public new T GetAt ( int index ) => ( T ) Inner [ index ] ;
220
244
221
- public IEnumerator < T > GetEnumerator ( ) => _inner . Cast < T > ( ) . GetEnumerator ( ) ;
222
- IEnumerator IEnumerable . GetEnumerator ( ) => _inner . GetEnumerator ( ) ;
245
+ public IEnumerator < T > GetEnumerator ( ) => Inner . Cast < T > ( ) . GetEnumerator ( ) ;
246
+ IEnumerator IEnumerable . GetEnumerator ( ) => Inner . GetEnumerator ( ) ;
223
247
224
248
public static new ItemsSourceView < T > GetOrCreate ( IEnumerable ? items )
225
249
{
0 commit comments