0
+ − 1 using System;
+ − 2
+ − 3 using System.Collections;
+ − 4 using System.Collections.Specialized;
+ − 5 using System.ComponentModel;
+ − 6 using System.Diagnostics;
+ − 7
+ − 8 using BLToolkit.EditableObjects;
+ − 9 using BLToolkit.Reflection;
+ − 10
+ − 11 namespace BLToolkit.ComponentModel
+ − 12 {
+ − 13 public class BindingListImpl: IBindingListView, ICancelAddNew, INotifyCollectionChanged
+ − 14 {
+ − 15 #region Init
+ − 16
+ − 17 public BindingListImpl(IList list, Type itemType)
+ − 18 {
+ − 19 if (list == null) throw new ArgumentNullException("list");
+ − 20 if (itemType == null) throw new ArgumentNullException("itemType");
+ − 21
+ − 22 _list = list;
+ − 23 _itemType = itemType;
+ − 24
+ − 25 AddInternal(_list);
+ − 26 }
+ − 27
+ − 28 #endregion
+ − 29
+ − 30 #region Protected Members
+ − 31
+ − 32 private readonly IList _list;
+ − 33 private readonly Type _itemType;
+ − 34
+ − 35 private void ApplySort(IComparer comparer)
+ − 36 {
+ − 37 if (_list is ISortable)
+ − 38 ((ISortable)_list).Sort(0, _list.Count, comparer);
+ − 39 else if (_list is ArrayList)
+ − 40 ((ArrayList)_list).Sort(0, _list.Count, comparer);
+ − 41 else if (_list is Array)
+ − 42 Array.Sort((Array)_list, comparer);
+ − 43 else
+ − 44 {
+ − 45 object[] items = new object[_list.Count];
+ − 46
+ − 47 _list.CopyTo(items, 0);
+ − 48 Array.Sort(items, comparer);
+ − 49
+ − 50 for (int i = 0; i < _list.Count; i++)
+ − 51 _list[i] = items[i];
+ − 52 }
+ − 53
+ − 54 _isSorted = true;
+ − 55 }
+ − 56
+ − 57 #endregion
+ − 58
+ − 59 #region IBindingList Members
+ − 60
+ − 61 #region Command
+ − 62
+ − 63 private int _newItemIndex = -1;
+ − 64 private INotifyObjectEdit _newObject;
+ − 65
+ − 66 public object AddNew()
+ − 67 {
+ − 68 if (AllowNew == false)
+ − 69 throw new NotSupportedException();
+ − 70
+ − 71 EndNew();
+ − 72
+ − 73 object o = TypeAccessor.CreateInstanceEx(_itemType);
+ − 74 _newObject = o as INotifyObjectEdit;
+ − 75
+ − 76 if (_newObject != null)
+ − 77 _newObject.ObjectEdit += NewObject_ObjectEdit;
+ − 78
+ − 79 _newItemIndex = _list.Add(o);
+ − 80 OnAddItem(o, _newItemIndex);
+ − 81
+ − 82 Debug.WriteLine(string.Format("AddNew - ({0})", o.GetType().Name));
+ − 83
+ − 84 return o;
+ − 85 }
+ − 86
+ − 87 void NewObject_ObjectEdit(object sender, ObjectEditEventArgs args)
+ − 88 {
+ − 89 if (sender == _newObject)
+ − 90 {
+ − 91 switch (args.EditType)
+ − 92 {
+ − 93 case ObjectEditType.End: EndNew(); break;
+ − 94 case ObjectEditType.Cancel: CancelNew(_newItemIndex); break;
+ − 95 default: return;
+ − 96 }
+ − 97 }
+ − 98 }
+ − 99
+ − 100 public bool AllowNew
+ − 101 {
+ − 102 get { return !_list.IsFixedSize; }
+ − 103 }
+ − 104
+ − 105 public bool AllowEdit
+ − 106 {
+ − 107 get { return !_list.IsReadOnly; }
+ − 108 }
+ − 109
+ − 110 public bool AllowRemove
+ − 111 {
+ − 112 get { return !_list.IsFixedSize; }
+ − 113 }
+ − 114
+ − 115 #endregion
+ − 116
+ − 117 #region Change Notification
+ − 118
+ − 119 private bool _notifyChanges = true;
+ − 120 public bool NotifyChanges
+ − 121 {
+ − 122 get { return _notifyChanges; }
+ − 123 set { _notifyChanges = value; }
+ − 124 }
+ − 125
+ − 126 public bool SupportsChangeNotification
+ − 127 {
+ − 128 get { return true; }
+ − 129 }
+ − 130
+ − 131 public event ListChangedEventHandler ListChanged;
+ − 132
+ − 133 private void FireListChangedEvent(object sender, ListChangedEventArgs e)
+ − 134 {
+ − 135 if (_notifyChanges && ListChanged != null)
+ − 136 ListChanged(sender, e);
+ − 137 }
+ − 138
+ − 139 protected virtual void OnListChanged(EditableListChangedEventArgs e)
+ − 140 {
+ − 141 FireListChangedEvent(this, e);
+ − 142 }
+ − 143
+ − 144 protected void OnListChanged(ListChangedType listChangedType, int index)
+ − 145 {
+ − 146 OnListChanged(new EditableListChangedEventArgs(listChangedType, index));
+ − 147 }
+ − 148
+ − 149 private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
+ − 150 {
+ − 151 if (_notifyChanges && sender != null)
+ − 152 {
+ − 153 int indexOfSender = _list.IndexOf(sender);
+ − 154
+ − 155 if (indexOfSender >= 0)
+ − 156 {
+ − 157 MemberAccessor ma = TypeAccessor.GetAccessor(sender.GetType())[e.PropertyName];
+ − 158
+ − 159 if (ma != null)
+ − 160 OnListChanged(new EditableListChangedEventArgs(indexOfSender, ma.PropertyDescriptor));
+ − 161 else
+ − 162 OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemChanged, indexOfSender));
+ − 163
+ − 164 // Do not fire an event for OnCollectionChanged here.
+ − 165
+ − 166 if (_isSorted && _list.Count > 1)
+ − 167 {
+ − 168 int newIndex = GetItemSortedPosition(indexOfSender, sender);
+ − 169
+ − 170 if (newIndex != indexOfSender)
+ − 171 {
+ − 172 _list.RemoveAt(indexOfSender);
+ − 173 _list.Insert(newIndex, sender);
+ − 174
+ − 175 OnMoveItem(sender, indexOfSender, newIndex);
+ − 176 }
+ − 177 }
+ − 178 }
+ − 179 }
+ − 180 }
+ − 181
+ − 182 #endregion
+ − 183
+ − 184 #region Sorting
+ − 185
+ − 186 public bool SupportsSorting
+ − 187 {
+ − 188 get { return true; }
+ − 189 }
+ − 190
+ − 191 [NonSerialized]
+ − 192 private bool _isSorted;
+ − 193 public bool IsSorted
+ − 194 {
+ − 195 get { return _isSorted; }
+ − 196 }
+ − 197
+ − 198 [NonSerialized]
+ − 199 private PropertyDescriptor _sortProperty;
+ − 200 public PropertyDescriptor SortProperty
+ − 201 {
+ − 202 get { return _sortProperty; }
+ − 203 }
+ − 204
+ − 205 [NonSerialized]
+ − 206 private ListSortDirection _sortDirection;
+ − 207 public ListSortDirection SortDirection
+ − 208 {
+ − 209 get { return _sortDirection; }
+ − 210 }
+ − 211
+ − 212 public void ApplySort(PropertyDescriptor property, ListSortDirection direction)
+ − 213 {
+ − 214 Debug.WriteLine(string.Format("Begin ApplySort(\"{0}\", {1})", property.Name, direction));
+ − 215
+ − 216 _sortProperty = property;
+ − 217 _sortDirection = direction;
+ − 218 _sortDescriptions = null;
+ − 219
+ − 220 ApplySort(GetSortComparer(_sortProperty, _sortDirection));
+ − 221
+ − 222 if (_list.Count > 0)
+ − 223 OnReset();
+ − 224
+ − 225 Debug.WriteLine(string.Format("End ApplySort(\"{0}\", {1})", property.Name, direction));
+ − 226 }
+ − 227
+ − 228 public void RemoveSort()
+ − 229 {
+ − 230 _isSorted = false;
+ − 231 _sortProperty = null;
+ − 232 _sortDescriptions = null;
+ − 233
+ − 234 OnReset();
+ − 235 }
+ − 236
+ − 237 #endregion
+ − 238
+ − 239 #region Searching
+ − 240
+ − 241 public bool SupportsSearching
+ − 242 {
+ − 243 get { return true; }
+ − 244 }
+ − 245
+ − 246 public int Find(PropertyDescriptor property, object key)
+ − 247 {
+ − 248 if (property == null) throw new ArgumentException("property");
+ − 249
+ − 250 if (key != null)
+ − 251 for (int i = 0; i < _list.Count; i++)
+ − 252 if (key.Equals(property.GetValue(_list[i])))
+ − 253 return i;
+ − 254
+ − 255 return -1;
+ − 256 }
+ − 257
+ − 258 #endregion
+ − 259
+ − 260 #region Indexes
+ − 261
+ − 262 public void AddIndex(PropertyDescriptor property)
+ − 263 {
+ − 264 }
+ − 265
+ − 266 public void RemoveIndex(PropertyDescriptor property)
+ − 267 {
+ − 268 }
+ − 269
+ − 270 #endregion
+ − 271
+ − 272 #endregion
+ − 273
+ − 274 #region ICancelAddNew Members
+ − 275
+ − 276 public void CancelNew(int itemIndex)
+ − 277 {
+ − 278 if (itemIndex >= 0 && itemIndex == _newItemIndex)
+ − 279 {
+ − 280 _list.RemoveAt(itemIndex);
+ − 281 OnRemoveItem(_newObject, itemIndex);
+ − 282 EndNew();
+ − 283 }
+ − 284 }
+ − 285
+ − 286 public void EndNew(int itemIndex)
+ − 287 {
+ − 288 if (itemIndex == _newItemIndex)
+ − 289 EndNew();
+ − 290 }
+ − 291
+ − 292 public void EndNew()
+ − 293 {
+ − 294 _newItemIndex = -1;
+ − 295
+ − 296 if (_newObject != null)
+ − 297 _newObject.ObjectEdit -= NewObject_ObjectEdit;
+ − 298
+ − 299 _newObject = null;
+ − 300 }
+ − 301
+ − 302 #endregion
+ − 303
+ − 304 #region IList Members
+ − 305
+ − 306 public int Add(object value)
+ − 307 {
+ − 308 int index;
+ − 309
+ − 310 if (!_isSorted)
+ − 311 index = _list.Add(value);
+ − 312 else
+ − 313 {
+ − 314 index = GetSortedInsertIndex(value);
+ − 315 _list.Insert(index, value);
+ − 316 }
+ − 317
+ − 318 AddInternal(value);
+ − 319 OnAddItem(value, index);
+ − 320
+ − 321 return index;
+ − 322 }
+ − 323
+ − 324 public void Clear()
+ − 325 {
+ − 326 if (_list.Count > 0)
+ − 327 {
+ − 328 RemoveInternal(_list);
+ − 329
+ − 330 _list.Clear();
+ − 331 OnReset();
+ − 332 }
+ − 333 }
+ − 334
+ − 335 public bool Contains(object value)
+ − 336 {
+ − 337 return _list.Contains(value);
+ − 338 }
+ − 339
+ − 340 public int IndexOf(object value)
+ − 341 {
+ − 342 return _list.IndexOf(value);
+ − 343 }
+ − 344
+ − 345 public void Insert(int index, object value)
+ − 346 {
+ − 347 if (_isSorted)
+ − 348 index = GetSortedInsertIndex(value);
+ − 349
+ − 350 _list.Insert(index, value);
+ − 351 AddInternal(value);
+ − 352
+ − 353 OnAddItem(value, index);
+ − 354 }
+ − 355
+ − 356 public bool IsFixedSize
+ − 357 {
+ − 358 get { return _list.IsFixedSize; }
+ − 359 }
+ − 360
+ − 361 public bool IsReadOnly
+ − 362 {
+ − 363 get { return _list.IsReadOnly; }
+ − 364 }
+ − 365
+ − 366 public void Remove(object value)
+ − 367 {
+ − 368 int index = IndexOf(value);
+ − 369
+ − 370 if (index >= 0)
+ − 371 RemoveInternal(value);
+ − 372
+ − 373 _list.Remove(value);
+ − 374
+ − 375 if (index >= 0)
+ − 376 OnRemoveItem(value, index);
+ − 377 }
+ − 378
+ − 379 public void RemoveAt(int index)
+ − 380 {
+ − 381 object value = this[index];
+ − 382
+ − 383 RemoveInternal(value);
+ − 384
+ − 385 _list.RemoveAt(index);
+ − 386
+ − 387 OnRemoveItem(value, index);
+ − 388 }
+ − 389
+ − 390 public object this[int index]
+ − 391 {
+ − 392 get { return _list[index]; }
+ − 393 set
+ − 394 {
+ − 395 object o = _list[index];
+ − 396
+ − 397 if (o != value)
+ − 398 {
+ − 399 RemoveInternal(o);
+ − 400
+ − 401 _list[index] = value;
+ − 402
+ − 403 AddInternal(value);
+ − 404
+ − 405 OnChangeItem(o, value, index);
+ − 406
+ − 407 if (_isSorted)
+ − 408 {
+ − 409 int newIndex = GetItemSortedPosition(index, value);
+ − 410
+ − 411 if (newIndex != index)
+ − 412 {
+ − 413 _list.RemoveAt(index);
+ − 414 _list.Insert(newIndex, value);
+ − 415 }
+ − 416
+ − 417 OnMoveItem(value, index, newIndex);
+ − 418 }
+ − 419 }
+ − 420 }
+ − 421 }
+ − 422
+ − 423 #endregion
+ − 424
+ − 425 #region ICollection Members
+ − 426
+ − 427 public void CopyTo(Array array, int index)
+ − 428 {
+ − 429 _list.CopyTo(array, index);
+ − 430 }
+ − 431
+ − 432 public int Count
+ − 433 {
+ − 434 get { return _list.Count; }
+ − 435 }
+ − 436
+ − 437 public bool IsSynchronized
+ − 438 {
+ − 439 get { return _list.IsSynchronized; }
+ − 440 }
+ − 441
+ − 442 public object SyncRoot
+ − 443 {
+ − 444 get { return _list.SyncRoot; }
+ − 445 }
+ − 446
+ − 447 #endregion
+ − 448
+ − 449 #region IEnumerable Members
+ − 450
+ − 451 public IEnumerator GetEnumerator()
+ − 452 {
+ − 453 return _list.GetEnumerator();
+ − 454 }
+ − 455
+ − 456 #endregion
+ − 457
+ − 458 #region SortPropertyComparer
+ − 459
+ − 460 class SortPropertyComparer : IComparer
+ − 461 {
+ − 462 readonly PropertyDescriptor _property;
+ − 463 readonly ListSortDirection _direction;
+ − 464
+ − 465 public SortPropertyComparer(PropertyDescriptor property, ListSortDirection direction)
+ − 466 {
+ − 467 _property = property;
+ − 468 _direction = direction;
+ − 469 }
+ − 470
+ − 471 public int Compare(object x, object y)
+ − 472 {
+ − 473 object a = _property.GetValue(x);
+ − 474 object b = _property.GetValue(y);
+ − 475
+ − 476 int n = Comparer.Default.Compare(a, b);
+ − 477
+ − 478 return _direction == ListSortDirection.Ascending? n: -n;
+ − 479 }
+ − 480 }
+ − 481
+ − 482 #endregion
+ − 483
+ − 484 #region IComparer Accessor
+ − 485
+ − 486 public IComparer GetSortComparer()
+ − 487 {
+ − 488 if (_isSorted)
+ − 489 {
+ − 490 if (_sortDescriptions != null)
+ − 491 return GetSortComparer(_sortDescriptions);
+ − 492
+ − 493 return GetSortComparer(_sortProperty, _sortDirection);
+ − 494 }
+ − 495
+ − 496 return null;
+ − 497 }
+ − 498
+ − 499 private IComparer GetSortComparer(PropertyDescriptor sortProperty, ListSortDirection sortDirection)
+ − 500 {
+ − 501 if (_sortSubstitutions.ContainsKey(sortProperty.Name))
+ − 502 sortProperty = ((SortSubstitutionPair)_sortSubstitutions[sortProperty.Name]).Substitute;
+ − 503
+ − 504 return new SortPropertyComparer(sortProperty, sortDirection);
+ − 505 }
+ − 506
+ − 507 private IComparer GetSortComparer(ListSortDescriptionCollection sortDescriptions)
+ − 508 {
+ − 509 bool needSubstitution = false;
+ − 510
+ − 511 if (_sortSubstitutions.Count > 0)
+ − 512 {
+ − 513 foreach (ListSortDescription sortDescription in sortDescriptions)
+ − 514 {
+ − 515 if (_sortSubstitutions.ContainsKey(sortDescription.PropertyDescriptor.Name))
+ − 516 {
+ − 517 needSubstitution = true;
+ − 518 break;
+ − 519 }
+ − 520 }
+ − 521
+ − 522 if (needSubstitution)
+ − 523 {
+ − 524 ListSortDescription[] sorts = new ListSortDescription[sortDescriptions.Count];
+ − 525 sortDescriptions.CopyTo(sorts, 0);
+ − 526
+ − 527 for (int i = 0; i < sorts.Length; i++)
+ − 528 if (_sortSubstitutions.ContainsKey(sorts[i].PropertyDescriptor.Name))
+ − 529 sorts[i] = new ListSortDescription(((SortSubstitutionPair)_sortSubstitutions[sorts[i].PropertyDescriptor.Name]).Substitute,
+ − 530 sorts[i].SortDirection);
+ − 531
+ − 532 sortDescriptions = new ListSortDescriptionCollection(sorts);
+ − 533 }
+ − 534 }
+ − 535
+ − 536 return new SortListPropertyComparer(sortDescriptions);
+ − 537 }
+ − 538
+ − 539 #endregion
+ − 540
+ − 541 #region IBindingListView Members
+ − 542
+ − 543 public bool SupportsAdvancedSorting
+ − 544 {
+ − 545 get { return true; }
+ − 546 }
+ − 547
+ − 548 public void ApplySort(ListSortDescriptionCollection sorts)
+ − 549 {
+ − 550 _sortDescriptions = sorts;
+ − 551
+ − 552 _isSorted = true;
+ − 553 _sortProperty = null;
+ − 554
+ − 555 ApplySort(GetSortComparer(sorts));
+ − 556
+ − 557 if (_list.Count > 0)
+ − 558 OnReset();
+ − 559 }
+ − 560
+ − 561 [NonSerialized]
+ − 562 private ListSortDescriptionCollection _sortDescriptions;
+ − 563 public ListSortDescriptionCollection SortDescriptions
+ − 564 {
+ − 565 get { return _sortDescriptions; }
+ − 566 }
+ − 567
+ − 568 public bool SupportsFiltering
+ − 569 {
+ − 570 get { return false; }
+ − 571 }
+ − 572
+ − 573 public string Filter
+ − 574 {
+ − 575 get { throw new NotImplementedException("The method 'BindingListImpl.get_Filter' is not implemented."); }
+ − 576 set { throw new NotImplementedException("The method 'BindingListImpl.set_Filter' is not implemented."); }
+ − 577 }
+ − 578
+ − 579 public void RemoveFilter()
+ − 580 {
+ − 581 throw new NotImplementedException("The method 'BindingListImpl.RemoveFilter()' is not implemented.");
+ − 582 }
+ − 583
+ − 584 #endregion
+ − 585
+ − 586 #region SortListPropertyComparer
+ − 587
+ − 588 class SortListPropertyComparer : IComparer
+ − 589 {
+ − 590 readonly ListSortDescriptionCollection _sorts;
+ − 591
+ − 592 public SortListPropertyComparer(ListSortDescriptionCollection sorts)
+ − 593 {
+ − 594 _sorts = sorts;
+ − 595 }
+ − 596
+ − 597 public int Compare(object x, object y)
+ − 598 {
+ − 599 for (int i = 0; i < _sorts.Count; i++)
+ − 600 {
+ − 601 PropertyDescriptor property = _sorts[i].PropertyDescriptor;
+ − 602
+ − 603 object a = property.GetValue(x);
+ − 604 object b = property.GetValue(y);
+ − 605
+ − 606 int n = Comparer.Default.Compare(a, b);
+ − 607
+ − 608 if (n != 0)
+ − 609 return _sorts[i].SortDirection == ListSortDirection.Ascending? n: -n;
+ − 610 }
+ − 611
+ − 612 return 0;
+ − 613 }
+ − 614 }
+ − 615
+ − 616 #endregion
+ − 617
+ − 618 #region Sorting enhancement
+ − 619
+ − 620 private readonly Hashtable _sortSubstitutions = new Hashtable();
+ − 621
+ − 622 private class SortSubstitutionPair
+ − 623 {
+ − 624 public SortSubstitutionPair(PropertyDescriptor original, PropertyDescriptor substitute)
+ − 625 {
+ − 626 Original = original;
+ − 627 Substitute = substitute;
+ − 628 }
+ − 629
+ − 630 public readonly PropertyDescriptor Original;
+ − 631 public readonly PropertyDescriptor Substitute;
+ − 632 }
+ − 633
+ − 634 public void CreateSortSubstitution(string originalProperty, string substituteProperty)
+ − 635 {
+ − 636 TypeAccessor typeAccessor = TypeAccessor.GetAccessor(_itemType);
+ − 637
+ − 638 PropertyDescriptor originalDescriptor = typeAccessor.PropertyDescriptors[originalProperty];
+ − 639 PropertyDescriptor substituteDescriptor = typeAccessor.PropertyDescriptors[substituteProperty];
+ − 640
+ − 641 if (originalDescriptor == null) throw new InvalidOperationException("Can not retrieve PropertyDescriptor for original property: " + originalProperty);
+ − 642 if (substituteDescriptor == null) throw new InvalidOperationException("Can not retrieve PropertyDescriptor for substitute property: " + substituteProperty);
+ − 643
+ − 644 _sortSubstitutions[originalProperty] = new SortSubstitutionPair(originalDescriptor, substituteDescriptor);
+ − 645 }
+ − 646
+ − 647 public void RemoveSortSubstitution(string originalProperty)
+ − 648 {
+ − 649 _sortSubstitutions.Remove(originalProperty);
+ − 650 }
+ − 651
+ − 652 #endregion
+ − 653
+ − 654 #region Sort enforcement
+ − 655
+ − 656 public int GetItemSortedPosition(int index, object sender)
+ − 657 {
+ − 658 IComparer comparer = GetSortComparer();
+ − 659
+ − 660 if (comparer == null)
+ − 661 return index;
+ − 662
+ − 663 if ((index > 0 && comparer.Compare(_list[index - 1], sender) > 0) ||
+ − 664 (index < _list.Count - 1 && comparer.Compare(_list[index + 1], sender) < 0))
+ − 665 {
+ − 666 for (int i = 0; i < _list.Count; i++)
+ − 667 {
+ − 668 if (i != index && comparer.Compare(_list[i], sender) > 0)
+ − 669 {
+ − 670 if (i > index)
+ − 671 return i - 1;
+ − 672
+ − 673 return i;
+ − 674 }
+ − 675 }
+ − 676
+ − 677 return _list.Count - 1;
+ − 678 }
+ − 679
+ − 680 return index;
+ − 681 }
+ − 682
+ − 683 public int GetSortedInsertIndex(object value)
+ − 684 {
+ − 685 IComparer comparer = GetSortComparer();
+ − 686
+ − 687 if (comparer == null)
+ − 688 return -1;
+ − 689
+ − 690 for (int i = 0; i < _list.Count; i++)
+ − 691 if (comparer.Compare(_list[i], value) > 0)
+ − 692 return i;
+ − 693
+ − 694 return _list.Count;
+ − 695 }
+ − 696
+ − 697 #endregion
+ − 698
+ − 699 #region Misc/Range Operations
+ − 700
+ − 701 public void Move(int newIndex, int oldIndex)
+ − 702 {
+ − 703 if (oldIndex != newIndex)
+ − 704 {
+ − 705 EndNew();
+ − 706
+ − 707 object o = _list[oldIndex];
+ − 708
+ − 709 _list.RemoveAt(oldIndex);
+ − 710 if (!_isSorted)
+ − 711 _list.Insert(newIndex, o);
+ − 712 else
+ − 713 _list.Insert(newIndex = GetSortedInsertIndex(o), o);
+ − 714
+ − 715 OnMoveItem(o, oldIndex, newIndex);
+ − 716 }
+ − 717 }
+ − 718
+ − 719 public void AddRange(ICollection c)
+ − 720 {
+ − 721 foreach (object o in c)
+ − 722 {
+ − 723 if (!_isSorted)
+ − 724 _list.Add(o);
+ − 725 else
+ − 726 _list.Insert(GetSortedInsertIndex(o), o);
+ − 727 }
+ − 728
+ − 729 AddInternal(c);
+ − 730
+ − 731 OnReset();
+ − 732 }
+ − 733
+ − 734 public void InsertRange(int index, ICollection c)
+ − 735 {
+ − 736 if (c.Count == 0)
+ − 737 return;
+ − 738
+ − 739 foreach (object o in c)
+ − 740 {
+ − 741 if (!_isSorted)
+ − 742 _list.Insert(index++, o);
+ − 743 else
+ − 744 _list.Insert(GetSortedInsertIndex(o), o);
+ − 745 }
+ − 746
+ − 747 AddInternal(c);
+ − 748
+ − 749 OnReset();
+ − 750 }
+ − 751
+ − 752 public void RemoveRange(int index, int count)
+ − 753 {
+ − 754 object[] toRemove = new object[count];
+ − 755
+ − 756 for (int i = index; i < _list.Count && i < index + count; i++)
+ − 757 toRemove[i - index] = _list[i];
+ − 758
+ − 759 RemoveInternal(toRemove);
+ − 760
+ − 761 foreach (object o in toRemove)
+ − 762 _list.Remove(o);
+ − 763
+ − 764 OnReset();
+ − 765 }
+ − 766
+ − 767 public void SetRange(int index, ICollection c)
+ − 768 {
+ − 769 int cCount = c.Count;
+ − 770
+ − 771 if (index < 0 || index >= _list.Count - cCount)
+ − 772 throw new ArgumentOutOfRangeException("index");
+ − 773
+ − 774 bool oldNotifyChanges = _notifyChanges;
+ − 775 _notifyChanges = false;
+ − 776
+ − 777 int i = index;
+ − 778 foreach (object newObject in c)
+ − 779 {
+ − 780 RemoveInternal(_list[i + index]);
+ − 781 _list[i + index] = newObject;
+ − 782 }
+ − 783
+ − 784 AddInternal(c);
+ − 785
+ − 786 if (_isSorted)
+ − 787 ApplySort(GetSortComparer());
+ − 788
+ − 789 _notifyChanges = oldNotifyChanges;
+ − 790 OnReset();
+ − 791 }
+ − 792
+ − 793 #endregion
+ − 794
+ − 795 #region Add/Remove Internal
+ − 796
+ − 797 private void AddInternal(object value)
+ − 798 {
+ − 799 EndNew();
+ − 800
+ − 801 if (value is INotifyPropertyChanged)
+ − 802 ((INotifyPropertyChanged)value).PropertyChanged +=
+ − 803 ItemPropertyChanged;
+ − 804 }
+ − 805
+ − 806 private void RemoveInternal(object value)
+ − 807 {
+ − 808 EndNew();
+ − 809
+ − 810 if (value is INotifyPropertyChanged)
+ − 811 ((INotifyPropertyChanged)value).PropertyChanged -=
+ − 812 ItemPropertyChanged;
+ − 813 }
+ − 814
+ − 815 private void AddInternal(IEnumerable e)
+ − 816 {
+ − 817 foreach (object o in e)
+ − 818 AddInternal(o);
+ − 819 }
+ − 820
+ − 821 private void RemoveInternal(IEnumerable e)
+ − 822 {
+ − 823 foreach (object o in e)
+ − 824 RemoveInternal(o);
+ − 825 }
+ − 826
+ − 827 private void OnAddItem(object item, int index)
+ − 828 {
+ − 829 OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemAdded, index));
+ − 830 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
+ − 831 }
+ − 832
+ − 833 private void OnRemoveItem(object item, int index)
+ − 834 {
+ − 835 OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemDeleted, index));
+ − 836 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
+ − 837 }
+ − 838
+ − 839 private void OnMoveItem(object item, int oldIndex, int newIndex)
+ − 840 {
+ − 841 OnListChanged(new EditableListChangedEventArgs(newIndex, oldIndex));
+ − 842 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, item, newIndex, oldIndex));
+ − 843 }
+ − 844
+ − 845 private void OnChangeItem(object oldValue, object newValue, int index)
+ − 846 {
+ − 847 OnListChanged(new EditableListChangedEventArgs(ListChangedType.ItemChanged, index));
+ − 848 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, oldValue, newValue, index));
+ − 849 }
+ − 850
+ − 851 private void OnReset()
+ − 852 {
+ − 853 OnListChanged(new EditableListChangedEventArgs(ListChangedType.Reset));
+ − 854 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+ − 855 }
+ − 856
+ − 857 #endregion
+ − 858
+ − 859 #region INotifyCollectionChanged Members
+ − 860
+ − 861 public event NotifyCollectionChangedEventHandler CollectionChanged;
+ − 862
+ − 863 private void FireCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs ea)
+ − 864 {
+ − 865 if (_notifyChanges && CollectionChanged != null)
+ − 866 CollectionChanged(sender, ea);
+ − 867 }
+ − 868
+ − 869 protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs ea)
+ − 870 {
+ − 871 FireCollectionChangedEvent(this, ea);
+ − 872 }
+ − 873
+ − 874 #endregion
+ − 875 }
+ − 876 }