CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
ExtendedBindingList.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="ExtendedBindingList.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Extends BindingList of T by adding extra</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.ComponentModel;
11#if NETFX_CORE || (ANDROID || IOS)
12using System.Collections.Generic;
13using System.Collections.Specialized;
14#endif
15
16namespace Csla.Core
17{
30 {
31 [NonSerialized()]
32 private EventHandler<RemovingItemEventArgs> _nonSerializableHandlers;
33 private EventHandler<RemovingItemEventArgs> _serializableHandlers;
34
38 public event EventHandler<RemovingItemEventArgs> RemovingItem
39 {
40 add
41 {
42 if (value.Method.IsPublic &&
43 (value.Method.DeclaringType.IsSerializable ||
44 value.Method.IsStatic))
45 _serializableHandlers = (EventHandler<RemovingItemEventArgs>)
46 System.Delegate.Combine(_serializableHandlers, value);
47 else
48 _nonSerializableHandlers = (EventHandler<RemovingItemEventArgs>)
49 System.Delegate.Combine(_nonSerializableHandlers, value);
50 }
51 remove
52 {
53 if (value.Method.IsPublic &&
54 (value.Method.DeclaringType.IsSerializable ||
55 value.Method.IsStatic))
56 _serializableHandlers = (EventHandler<RemovingItemEventArgs>)
57 System.Delegate.Remove(_serializableHandlers, value);
58 else
59 _nonSerializableHandlers = (EventHandler<RemovingItemEventArgs>)
60 System.Delegate.Remove(_nonSerializableHandlers, value);
61 }
62 }
63
71 [EditorBrowsable(EditorBrowsableState.Advanced)]
72 protected void OnRemovingItem(T removedItem)
73 {
74 if (_nonSerializableHandlers != null)
75 _nonSerializableHandlers.Invoke(this,
76 new RemovingItemEventArgs(removedItem));
77 if (_serializableHandlers != null)
78 _serializableHandlers.Invoke(this,
79 new RemovingItemEventArgs(removedItem));
80 }
81
90 protected override void RemoveItem(int index)
91 {
92 OnRemovingItem(this[index]);
93 OnRemoveEventHooks(this[index]);
94 base.RemoveItem(index);
95 }
96
101 public void AddRange(System.Collections.Generic.IEnumerable<T> range)
102 {
103 foreach (var element in range)
104 this.Add(element);
105 }
106
107 [NotUndoable]
108 [NonSerialized]
109 private BusyChangedEventHandler _busyChanged = null;
110
116 {
117 add { _busyChanged = (BusyChangedEventHandler)Delegate.Combine(_busyChanged, value); }
118 remove { _busyChanged = (BusyChangedEventHandler)Delegate.Remove(_busyChanged, value); }
119 }
120
126 protected virtual void OnBusyChanged(BusyChangedEventArgs args)
127 {
128 if (_busyChanged != null)
129 _busyChanged(this, args);
130 }
131
137 protected void OnBusyChanged(string propertyName, bool busy)
138 {
139 OnBusyChanged(new BusyChangedEventArgs(propertyName, busy));
140 }
141
145 [Browsable(false)]
146 [System.ComponentModel.DataAnnotations.Display(AutoGenerateField = false)]
147 [System.ComponentModel.DataAnnotations.ScaffoldColumn(false)]
148 public virtual bool IsBusy
149 {
150 get { throw new NotImplementedException(); }
151 }
152
156 [Browsable(false)]
157 [System.ComponentModel.DataAnnotations.Display(AutoGenerateField = false)]
158 [System.ComponentModel.DataAnnotations.ScaffoldColumn(false)]
159 public virtual bool IsSelfBusy
160 {
161 get { return IsBusy; }
162 }
163
164 void busy_BusyChanged(object sender, BusyChangedEventArgs e)
165 {
166 OnBusyChanged(e);
167 }
168
169 [NotUndoable]
170 [NonSerialized]
171 private EventHandler<ErrorEventArgs> _unhandledAsyncException;
172
177 public event EventHandler<ErrorEventArgs> UnhandledAsyncException
178 {
179 add { _unhandledAsyncException = (EventHandler<ErrorEventArgs>)Delegate.Combine(_unhandledAsyncException, value); }
180 remove { _unhandledAsyncException = (EventHandler<ErrorEventArgs>)Delegate.Remove(_unhandledAsyncException, value); }
181 }
182
188 protected virtual void OnUnhandledAsyncException(ErrorEventArgs error)
189 {
190 if (_unhandledAsyncException != null)
191 _unhandledAsyncException(this, error);
192 }
193
199 protected void OnUnhandledAsyncException(object originalSender, Exception error)
200 {
201 OnUnhandledAsyncException(new ErrorEventArgs(originalSender, error));
202 }
203
204 void unhandled_UnhandledAsyncException(object sender, ErrorEventArgs e)
205 {
207 }
208
214 protected override void InsertItem(int index, T item)
215 {
216 base.InsertItem(index, item);
217 OnAddEventHooks(item);
218 }
219
225 [EditorBrowsable(EditorBrowsableState.Never)]
226 protected virtual void OnAddEventHooks(T item)
227 {
228 INotifyBusy busy = item as INotifyBusy;
229 if (busy != null)
230 busy.BusyChanged += new BusyChangedEventHandler(busy_BusyChanged);
231
233 if (unhandled != null)
234 unhandled.UnhandledAsyncException += new EventHandler<ErrorEventArgs>(unhandled_UnhandledAsyncException);
235
236 INotifyPropertyChanged c = item as INotifyPropertyChanged;
237 if (c != null)
238 c.PropertyChanged += Child_PropertyChanged;
239
241 if (child != null)
242 child.ChildChanged += Child_Changed;
243 }
244
250 [EditorBrowsable(EditorBrowsableState.Never)]
251 protected virtual void OnRemoveEventHooks(T item)
252 {
253 INotifyBusy busy = item as INotifyBusy;
254 if (busy != null)
255 busy.BusyChanged -= new BusyChangedEventHandler(busy_BusyChanged);
256
258 if (unhandled != null)
259 unhandled.UnhandledAsyncException -= new EventHandler<ErrorEventArgs>(unhandled_UnhandledAsyncException);
260
261 INotifyPropertyChanged c = item as INotifyPropertyChanged;
262 if (c != null)
263 c.PropertyChanged -= new PropertyChangedEventHandler(Child_PropertyChanged);
264
266 if (child != null)
267 child.ChildChanged -= new EventHandler<ChildChangedEventArgs>(Child_Changed);
268 }
269
274 [EditorBrowsable(EditorBrowsableState.Advanced)]
275 protected virtual void OnDeserialized()
276 {
277 // do nothing - this is here so a subclass
278 // could override if needed
279 }
280
282 {
283 // don't rehook events here, because the MobileFormatter has
284 // created new objects and so the lists will auto-subscribe
285 // the events
287 }
288
289 [System.Runtime.Serialization.OnDeserialized]
290 private void OnDeserializedHandler(System.Runtime.Serialization.StreamingContext context)
291 {
292 foreach (T item in this)
293 OnAddEventHooks(item);
294
296 }
297
298 [NonSerialized]
299 [NotUndoable]
300 private EventHandler<Csla.Core.ChildChangedEventArgs> _childChangedHandlers;
301
305 public event EventHandler<Csla.Core.ChildChangedEventArgs> ChildChanged
306 {
307 add
308 {
309 _childChangedHandlers = (EventHandler<Csla.Core.ChildChangedEventArgs>)
310 System.Delegate.Combine(_childChangedHandlers, value);
311 }
312 remove
313 {
314 _childChangedHandlers = (EventHandler<Csla.Core.ChildChangedEventArgs>)
315 System.Delegate.Remove(_childChangedHandlers, value);
316 }
317 }
318
326 [EditorBrowsable(EditorBrowsableState.Advanced)]
327 protected virtual void OnChildChanged(ChildChangedEventArgs e)
328 {
329 if (_childChangedHandlers != null)
330 _childChangedHandlers.Invoke(this, e);
331 }
332
333#if NETFX_CORE || (ANDROID || IOS)
334
338 private void RaiseChildChanged(
339 object childObject, PropertyChangedEventArgs propertyArgs, NotifyCollectionChangedEventArgs listArgs)
340 {
341 ChildChangedEventArgs args = new ChildChangedEventArgs(childObject, propertyArgs, listArgs);
342 OnChildChanged(args);
343 }
344
350 [EditorBrowsable(EditorBrowsableState.Never)]
351 protected virtual void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
352 {
353 RaiseChildChanged(sender, e, null);
354 }
355
361 private void Child_Changed(object sender, ChildChangedEventArgs e)
362 {
363 RaiseChildChanged(e.ChildObject, e.PropertyChangedArgs, e.CollectionChangedArgs);
364 }
365#else
369 private void RaiseChildChanged(
370 object childObject, PropertyChangedEventArgs propertyArgs, ListChangedEventArgs listArgs)
371 {
372 ChildChangedEventArgs args = new ChildChangedEventArgs(childObject, propertyArgs, listArgs);
373 OnChildChanged(args);
374 }
375
383 [EditorBrowsable(EditorBrowsableState.Never)]
384 protected virtual void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
385 {
386 RaiseChildChanged(sender, e, null);
387 }
388
394 private void Child_Changed(object sender, ChildChangedEventArgs e)
395 {
396 RaiseChildChanged(e.ChildObject, e.PropertyChangedArgs, e.ListChangedArgs);
397 }
398#endif
399
404 public IDisposable SuppressListChangedEvents
405 {
406 get { return new SuppressListChangedEventsClass<T>(this); }
407 }
408
414 class SuppressListChangedEventsClass<TC> : IDisposable
415 {
416 private readonly BindingList<TC> _businessObject;
417 private readonly bool _initialRaiseListChangedEvents;
418
419 public SuppressListChangedEventsClass(BindingList<TC> businessObject)
420 {
421 this._businessObject = businessObject;
422 _initialRaiseListChangedEvents = businessObject.RaiseListChangedEvents;
423 businessObject.RaiseListChangedEvents = false;
424 }
425
426 public void Dispose()
427 {
428 _businessObject.RaiseListChangedEvents = _initialRaiseListChangedEvents;
429 }
430 }
431 }
432}
Event arguments for the BusyChanged event.
Contains event data about the changed child object.
PropertyChangedEventArgs PropertyChangedArgs
Gets the PropertyChangedEventArgs object from the child's PropertyChanged event, if the child is not ...
object ChildObject
Gets a reference to the changed child object.
ListChangedEventArgs ListChangedArgs
Gets the ListChangedEventArgs object from the child's ListChanged event, if the child is a collection...
Event arguments for an unhandled async exception.
Extends BindingList of T by adding extra behaviors.
virtual void OnDeserialized()
This method is called on a newly deserialized object after deserialization is complete.
IDisposable SuppressListChangedEvents
Use this object to suppress ListChangedEvents for an entire code block.
void OnRemovingItem(T removedItem)
Raise the RemovingItem event.
virtual void OnUnhandledAsyncException(ErrorEventArgs error)
Method invoked when an unhandled async exception has occurred.
override void InsertItem(int index, T item)
Invoked when an item is inserted into the list.
void OnBusyChanged(string propertyName, bool busy)
Raises the BusyChanged event for a specific property.
BusyChangedEventHandler BusyChanged
Event indicating that the busy status of the object has changed.
virtual bool IsSelfBusy
Gets the busy status for this object.
EventHandler< Csla.Core.ChildChangedEventArgs > ChildChanged
Event raised when a child object has been changed.
virtual void Child_PropertyChanged(object sender, PropertyChangedEventArgs e)
Handles any PropertyChanged event from a child object and echoes it up as a ChildChanged event.
virtual bool IsBusy
Gets the busy status for this object and its child objects.
EventHandler< RemovingItemEventArgs > RemovingItem
Implements a serialization-safe RemovingItem event.
override void RemoveItem(int index)
Remove the item at the specified index.
virtual void OnAddEventHooks(T item)
Method invoked when events are hooked for a child object.
virtual void OnChildChanged(ChildChangedEventArgs e)
Raises the ChildChanged event, indicating that a child object has been changed.
virtual void OnBusyChanged(BusyChangedEventArgs args)
Override this method to be notified when the IsBusy property has changed.
virtual void OnRemoveEventHooks(T item)
Method invoked when events are unhooked for a child object.
void OnUnhandledAsyncException(object originalSender, Exception error)
Raises the UnhandledAsyncException event.
EventHandler< ErrorEventArgs > UnhandledAsyncException
Event indicating that an exception occurred during an async operation.
void AddRange(System.Collections.Generic.IEnumerable< T > range)
Add a range of items to the list.
Inherit from this base class to easily create a serializable list class.
Contains event data for the RemovingItem event.
Extends IBindingList by adding extra events.
Interface defining an object that notifies when it is busy executing an asynchronous operation.
Definition: INotifyBusy.cs:17
BusyChangedEventHandler BusyChanged
Event raised when the object's busy status changes.
Definition: INotifyBusy.cs:22
Implemented by classes that notify when a child object has changed.
EventHandler< ChildChangedEventArgs > ChildChanged
Event indictating that a child object has changed.
Implemented by an object that perfoms asynchronous operations that may raise exceptions.
EventHandler< ErrorEventArgs > UnhandledAsyncException
Event indicating that an exception occurred during an asynchronous operation.
Extension of IMobileObject for list types
Definition: IMobileList.cs:14
Interface defining callback methods used by the SerializationFormatterFactory.GetFormatter().
void Deserialized()
Method called on an object after deserialization is complete.
delegate void BusyChangedEventHandler(object sender, BusyChangedEventArgs e)
Delegate for handling the BusyChanged event.
@ Serializable
Prevents updating or inserting until the transaction is complete.