3 using System.ComponentModel;
4 using System.ComponentModel.Design.Serialization;
5 using System.Collections.Generic;
9 namespace MonoTests.System.ComponentModel
12 public class BindingListTest
15 public void BindingListDefaults ()
17 BindingList<string> l = new BindingList<string> ();
18 IBindingList ibl = (IBindingList)l;
20 Assert.IsTrue (l.AllowEdit, "1");
21 Assert.IsFalse (l.AllowNew, "2");
22 Assert.IsTrue (l.AllowRemove, "3");
23 Assert.IsTrue (l.RaiseListChangedEvents, "4");
25 Assert.IsFalse (ibl.IsSorted, "5");
26 Assert.AreEqual (ibl.SortDirection, ListSortDirection.Ascending, "6");
27 Assert.IsTrue (ibl.SupportsChangeNotification, "7");
28 Assert.IsFalse (ibl.SupportsSearching, "8");
29 Assert.IsFalse (ibl.SupportsSorting, "9");
30 Assert.IsFalse (((IRaiseItemChangedEvents)l).RaisesItemChangedEvents, "10");
34 public void BindingListDefaults_FixedSizeList ()
36 string[] arr = new string[10];
37 BindingList<string> l = new BindingList<string> (arr);
38 IBindingList ibl = (IBindingList)l;
40 Assert.IsTrue (l.AllowEdit, "1");
41 Assert.IsFalse (l.AllowNew, "2");
42 Assert.IsTrue (l.AllowRemove, "3");
43 Assert.IsTrue (l.RaiseListChangedEvents, "4");
45 Assert.IsFalse (ibl.IsSorted, "5");
46 Assert.AreEqual (ibl.SortDirection, ListSortDirection.Ascending, "6");
47 Assert.IsTrue (ibl.SupportsChangeNotification, "7");
48 Assert.IsFalse (ibl.SupportsSearching, "8");
49 Assert.IsFalse (ibl.SupportsSorting, "9");
50 Assert.IsFalse (((IRaiseItemChangedEvents)l).RaisesItemChangedEvents, "10");
54 public void BindingListDefaults_NonFixedSizeList ()
56 List<string> list = new List<string> ();
57 BindingList<string> l = new BindingList<string> (list);
58 IBindingList ibl = (IBindingList)l;
60 Assert.IsTrue (l.AllowEdit, "1");
61 Assert.IsFalse (l.AllowNew, "2");
62 Assert.IsTrue (l.AllowRemove, "3");
63 Assert.IsTrue (l.RaiseListChangedEvents, "4");
65 Assert.IsFalse (ibl.IsSorted, "5");
66 Assert.AreEqual (ibl.SortDirection, ListSortDirection.Ascending, "6");
67 Assert.IsTrue (ibl.SupportsChangeNotification, "7");
68 Assert.IsFalse (ibl.SupportsSearching, "8");
69 Assert.IsFalse (ibl.SupportsSorting, "9");
70 Assert.IsFalse (((IRaiseItemChangedEvents)l).RaisesItemChangedEvents, "10");
74 public void BindingListDefaults_ReadOnlyList ()
76 List<string> list = new List<string> ();
77 BindingList<string> l = new BindingList<string> (list);
78 IBindingList ibl = (IBindingList)l;
80 Assert.IsTrue (l.AllowEdit, "1");
81 Assert.IsFalse (l.AllowNew, "2");
82 Assert.IsTrue (l.AllowRemove, "3");
83 Assert.IsTrue (l.RaiseListChangedEvents, "4");
85 Assert.IsFalse (ibl.IsSorted, "5");
86 Assert.AreEqual (ibl.SortDirection, ListSortDirection.Ascending, "6");
87 Assert.IsTrue (ibl.SupportsChangeNotification, "7");
88 Assert.IsFalse (ibl.SupportsSearching, "8");
89 Assert.IsFalse (ibl.SupportsSorting, "9");
90 Assert.IsFalse (((IRaiseItemChangedEvents)l).RaisesItemChangedEvents, "10");
94 public void TestAllowNew ()
96 /* Object has a default ctor */
97 BindingList<object> l1 = new BindingList<object> ();
98 Assert.IsTrue (l1.AllowNew, "1");
100 /* string has no default ctor */
101 BindingList<string> l2 = new BindingList<string> ();
102 Assert.IsFalse (l2.AllowNew, "2");
104 /* adding a delegate to AddingNew fixes that */
105 l2.AddingNew += delegate (object sender, AddingNewEventArgs e) { };
106 Assert.IsTrue (l2.AllowNew, "3");
108 l1 = new BindingList<object> ();
110 bool list_changed = false;
111 bool expected = false;
113 l1.ListChanged += delegate (object sender, ListChangedEventArgs e) {
115 Assert.AreEqual (-1, e.NewIndex, "4");
116 Assert.AreEqual (ListChangedType.Reset, e.ListChangedType, "5");
117 Assert.AreEqual (expected, l1.AllowNew, "6");
123 Assert.IsTrue (list_changed, "7");
125 /* the default for T=object is true, so check
126 if we enter the block for raising the event
127 if we explicitly set it to the value it
129 l1 = new BindingList<object> ();
131 list_changed = false;
133 l1.ListChanged += delegate (object sender, ListChangedEventArgs e) {
135 Assert.AreEqual (-1, e.NewIndex, "8");
136 Assert.AreEqual (ListChangedType.Reset, e.ListChangedType, "9");
137 Assert.AreEqual (expected, l1.AllowNew, "10");
143 /* turns out it doesn't raise the event, so the check must only be for "allow_new == value" */
144 Assert.IsFalse (list_changed, "11");
148 public void TestResetBindings ()
150 BindingList<object> l = new BindingList<object> ();
152 bool list_changed = false;
154 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
156 Assert.AreEqual (-1, e.NewIndex, "1");
157 Assert.AreEqual (ListChangedType.Reset, e.ListChangedType, "2");
162 Assert.IsTrue (list_changed, "3");
166 public void TestResetItem ()
168 List<object> list = new List<object>();
169 list.Add (new object());
171 BindingList<object> l = new BindingList<object> (list);
173 bool item_changed = false;
175 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
177 Assert.AreEqual (0, e.NewIndex, "1");
178 Assert.AreEqual (ListChangedType.ItemChanged, e.ListChangedType, "2");
183 Assert.IsTrue (item_changed, "3");
187 public void TestRemoveItem ()
189 List<object> list = new List<object>();
190 list.Add (new object());
192 BindingList<object> l = new BindingList<object> (list);
194 bool item_deleted = false;
196 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
198 Assert.AreEqual (0, e.NewIndex, "1");
199 Assert.AreEqual (ListChangedType.ItemDeleted, e.ListChangedType, "2");
200 Assert.AreEqual (0, l.Count, "3"); // to show the event is raised after the removal
205 Assert.IsTrue (item_deleted, "4");
209 [ExpectedException (typeof (NotSupportedException))]
210 public void TestRemoveItem_AllowRemoveFalse ()
212 List<object> list = new List<object>();
213 list.Add (new object());
215 BindingList<object> l = new BindingList<object> (list);
217 l.AllowRemove = false;
223 public void TestAllowEditEvent ()
225 BindingList<object> l = new BindingList<object>();
227 bool event_raised = false;
228 bool expected = false;
230 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
232 Assert.AreEqual (-1, e.NewIndex, "1");
233 Assert.AreEqual (ListChangedType.Reset, e.ListChangedType, "2");
234 Assert.AreEqual (expected, l.AllowEdit, "3");
240 Assert.IsTrue (event_raised, "4");
242 // check to see if RaiseListChangedEvents affects AllowEdit's event.
243 l.RaiseListChangedEvents = false;
245 event_raised = false;
249 Assert.IsFalse (event_raised, "5");
253 public void TestAllowRemove ()
255 BindingList<object> l = new BindingList<object>();
257 bool event_raised = false;
258 bool expected = false;
260 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
262 Assert.AreEqual (-1, e.NewIndex, "1");
263 Assert.AreEqual (ListChangedType.Reset, e.ListChangedType, "2");
264 Assert.AreEqual (expected, l.AllowRemove, "3");
268 l.AllowRemove = false;
270 Assert.IsTrue (event_raised, "4");
272 // check to see if RaiseListChangedEvents affects AllowRemove's event.
273 l.RaiseListChangedEvents = false;
275 event_raised = false;
277 l.AllowRemove = true;
279 Assert.IsFalse (event_raised, "5");
283 public void TestAddNew_SettingArgsNewObject ()
285 BindingList<object> l = new BindingList<object>();
287 bool adding_event_raised = false;
288 object o = new object ();
290 l.AddingNew += delegate (object sender, AddingNewEventArgs e) {
291 adding_event_raised = true;
292 Assert.IsNull (e.NewObject, "1");
296 object rv = l.AddNew ();
297 Assert.IsTrue (adding_event_raised, "2");
298 Assert.AreSame (o, rv, "3");
302 public void TestAddNew ()
304 BindingList<object> l = new BindingList<object>();
306 bool adding_event_raised = false;
307 object o = new object ();
309 l.AddingNew += delegate (object sender, AddingNewEventArgs e) {
310 adding_event_raised = true;
311 Assert.IsNull (e.NewObject, "1");
314 object rv = l.AddNew ();
315 Assert.IsTrue (adding_event_raised, "2");
316 Assert.IsNotNull (rv, "3");
320 public void TestAddNew_Cancel ()
322 BindingList<object> l = new BindingList<object>();
324 bool adding_event_raised = false;
325 object o = new object ();
327 bool list_changed = false;
328 ListChangedType change_type = ListChangedType.Reset;
329 int list_changed_index = -1;
331 l.AddingNew += delegate (object sender, AddingNewEventArgs e) {
332 adding_event_raised = true;
333 Assert.IsNull (e.NewObject, "1");
336 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
338 change_type = e.ListChangedType;
339 list_changed_index = e.NewIndex;
342 object rv = l.AddNew ();
343 Assert.IsTrue (adding_event_raised, "2");
344 Assert.IsNotNull (rv, "3");
346 Assert.AreEqual (1, l.Count, "4");
347 Assert.AreEqual (0, l.IndexOf (rv), "5");
348 Assert.IsTrue (list_changed, "6");
349 Assert.AreEqual (ListChangedType.ItemAdded, change_type, "7");
350 Assert.AreEqual (0, list_changed_index, "8");
352 list_changed = false;
356 Assert.AreEqual (0, l.Count, "9");
357 Assert.IsTrue (list_changed, "10");
358 Assert.AreEqual (ListChangedType.ItemDeleted, change_type, "11");
359 Assert.AreEqual (0, list_changed_index, "12");
363 public void TestAddNew_CancelDifferentIndex ()
365 List<object> list = new List<object>();
367 list.Add (new object ());
368 list.Add (new object ());
370 BindingList<object> l = new BindingList<object>(list);
372 bool adding_event_raised = false;
373 object o = new object ();
375 bool list_changed = false;
376 ListChangedType change_type = ListChangedType.Reset;
377 int list_changed_index = -1;
379 l.AddingNew += delegate (object sender, AddingNewEventArgs e) {
380 adding_event_raised = true;
381 Assert.IsNull (e.NewObject, "1");
384 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
386 change_type = e.ListChangedType;
387 list_changed_index = e.NewIndex;
390 object rv = l.AddNew ();
391 Assert.IsTrue (adding_event_raised, "2");
392 Assert.IsNotNull (rv, "3");
394 Assert.AreEqual (3, l.Count, "4");
395 Assert.AreEqual (2, l.IndexOf (rv), "5");
396 Assert.IsTrue (list_changed, "6");
397 Assert.AreEqual (ListChangedType.ItemAdded, change_type, "7");
398 Assert.AreEqual (2, list_changed_index, "8");
400 list_changed = false;
404 Assert.IsFalse (list_changed, "9");
405 Assert.AreEqual (3, l.Count, "10");
409 Assert.IsTrue (list_changed, "11");
410 Assert.AreEqual (ListChangedType.ItemDeleted, change_type, "12");
411 Assert.AreEqual (2, list_changed_index, "13");
412 Assert.AreEqual (2, l.Count, "14");
416 public void TestAddNew_End ()
418 BindingList<object> l = new BindingList<object>();
420 bool adding_event_raised = false;
421 object o = new object ();
423 bool list_changed = false;
424 ListChangedType change_type = ListChangedType.Reset;
425 int list_changed_index = -1;
427 l.AddingNew += delegate (object sender, AddingNewEventArgs e) {
428 adding_event_raised = true;
429 Assert.IsNull (e.NewObject, "1");
432 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
434 change_type = e.ListChangedType;
435 list_changed_index = e.NewIndex;
438 object rv = l.AddNew ();
439 Assert.IsTrue (adding_event_raised, "2");
440 Assert.IsNotNull (rv, "3");
442 Assert.AreEqual (1, l.Count, "4");
443 Assert.AreEqual (0, l.IndexOf (rv), "5");
444 Assert.IsTrue (list_changed, "6");
445 Assert.AreEqual (ListChangedType.ItemAdded, change_type, "7");
446 Assert.AreEqual (0, list_changed_index, "8");
448 list_changed = false;
452 Assert.AreEqual (1, l.Count, "9");
453 Assert.IsFalse (list_changed, "10");
457 public void TestAddNew_CancelDifferentIndexThenEnd ()
459 BindingList<object> l = new BindingList<object>();
461 bool adding_event_raised = false;
462 object o = new object ();
464 bool list_changed = false;
465 ListChangedType change_type = ListChangedType.Reset;
466 int list_changed_index = -1;
468 l.AddingNew += delegate (object sender, AddingNewEventArgs e) {
469 adding_event_raised = true;
470 Assert.IsNull (e.NewObject, "1");
473 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
475 change_type = e.ListChangedType;
476 list_changed_index = e.NewIndex;
479 object rv = l.AddNew ();
480 Assert.IsTrue (adding_event_raised, "2");
481 Assert.IsNotNull (rv, "3");
483 Assert.AreEqual (1, l.Count, "4");
484 Assert.AreEqual (0, l.IndexOf (rv), "5");
485 Assert.IsTrue (list_changed, "6");
486 Assert.AreEqual (ListChangedType.ItemAdded, change_type, "7");
487 Assert.AreEqual (0, list_changed_index, "8");
489 list_changed = false;
493 Assert.AreEqual (1, l.Count, "9");
494 Assert.IsFalse (list_changed, "10");
498 Assert.AreEqual (1, l.Count, "11");
499 Assert.IsFalse (list_changed, "12");
503 public void TestAddNew_EndDifferentIndexThenCancel ()
505 BindingList<object> l = new BindingList<object>();
507 bool adding_event_raised = false;
508 object o = new object ();
510 bool list_changed = false;
511 ListChangedType change_type = ListChangedType.Reset;
512 int list_changed_index = -1;
514 l.AddingNew += delegate (object sender, AddingNewEventArgs e) {
515 adding_event_raised = true;
516 Assert.IsNull (e.NewObject, "1");
519 l.ListChanged += delegate (object sender, ListChangedEventArgs e) {
521 change_type = e.ListChangedType;
522 list_changed_index = e.NewIndex;
525 object rv = l.AddNew ();
526 Assert.IsTrue (adding_event_raised, "2");
527 Assert.IsNotNull (rv, "3");
529 Assert.AreEqual (1, l.Count, "4");
530 Assert.AreEqual (0, l.IndexOf (rv), "5");
531 Assert.IsTrue (list_changed, "6");
532 Assert.AreEqual (ListChangedType.ItemAdded, change_type, "7");
533 Assert.AreEqual (0, list_changed_index, "8");
535 list_changed = false;
539 Assert.AreEqual (1, l.Count, "9");
540 Assert.IsFalse (list_changed, "10");
544 Assert.IsTrue (list_changed, "11");
545 Assert.AreEqual (ListChangedType.ItemDeleted, change_type, "12");
546 Assert.AreEqual (0, list_changed_index, "13");
549 class BindingListPoker : BindingList<object>
551 public object DoAddNewCore()
553 return base.AddNewCore ();
557 // test to make sure that the events are raised in AddNewCore and not in AddNew
559 public void TestAddNewCore_Insert ()
561 BindingListPoker poker = new BindingListPoker ();
563 bool adding_event_raised = false;
565 bool list_changed = false;
566 ListChangedType change_type = ListChangedType.Reset;
567 int list_changed_index = -1;
569 poker.AddingNew += delegate (object sender, AddingNewEventArgs e) {
570 adding_event_raised = true;
573 poker.ListChanged += delegate (object sender, ListChangedEventArgs e) {
575 change_type = e.ListChangedType;
576 list_changed_index = e.NewIndex;
579 object o = poker.DoAddNewCore ();
581 Assert.IsTrue (adding_event_raised, "1");
582 Assert.IsTrue (list_changed, "2");
583 Assert.AreEqual (ListChangedType.ItemAdded, change_type, "3");
584 Assert.AreEqual (0, list_changed_index, "4");
585 Assert.AreEqual (1, poker.Count, "5");
588 private class Item : INotifyPropertyChanged {
590 public event PropertyChangedEventHandler PropertyChanged;
595 get { return _name; }
597 if (_name != value) {
599 OnPropertyChanged ("Name");
604 void OnPropertyChanged (string name)
606 var fn = PropertyChanged;
608 fn (this, new PropertyChangedEventArgs (name));
612 [Test] // https://bugzilla.xamarin.com/show_bug.cgi?id=8366
613 public void Bug8366 ()
616 bool changed = false;
617 var list = new BindingList<Item> ();
618 list.ListChanged += (object sender, ListChangedEventArgs e) => {
619 added |= e.ListChangedType == ListChangedType.ItemAdded;
620 changed |= e.ListChangedType == ListChangedType.ItemChanged;
623 var item = new Item () { Name = "1" };
628 Assert.IsTrue (added, "ItemAdded");
629 Assert.IsTrue (changed, "ItemChanged");
632 [Test] // https://bugzilla.xamarin.com/show_bug.cgi?id=16902
633 public void Bug16902 ()
635 var list = new BindingList<Item> ();
636 list.Insert (0, null);
637 var count = list.Count;
639 Assert.AreEqual (1, count, "1");
642 private class Person : INotifyPropertyChanged
644 private string _lastName;
645 private string _firstName;
647 public string FirstName {
648 get { return _firstName; }
651 OnPropertyChanged ("FirstName"); // string matches property name
655 public string LastName {
656 get { return _lastName; }
659 OnPropertyChanged ("Apepe"); // string doesn't match property name
663 public event PropertyChangedEventHandler PropertyChanged;
665 protected virtual void OnPropertyChanged (string propertyName = null)
667 PropertyChangedEventHandler handler = PropertyChanged;
669 handler (this, new PropertyChangedEventArgs (propertyName));
673 [Test] // https://bugzilla.xamarin.com/show_bug.cgi?id=20672
674 public void Bug20672 ()
676 string changedPropertyName = string.Empty;
677 bool isEventRaised = false;
678 bool? hasPropertyDescriptor = false;
680 var persons = new BindingList<Person>();
681 persons.Add (new Person() { FirstName = "Stefaan", LastName = "de Vogelaere" });
682 persons.Add (new Person() { FirstName = "Christophe", LastName = "De Langhe" });
683 persons.ListChanged += (object sender, ListChangedEventArgs e) => {
684 isEventRaised = true;
685 hasPropertyDescriptor = e.PropertyDescriptor != null;
688 //if the OnPropertyChanged string matches a valid property name, PropertyDescriptor should be generated
689 persons[0].FirstName = "Stefan";
690 Assert.IsTrue (isEventRaised);
691 Assert.IsTrue ((bool) hasPropertyDescriptor, "#1");
693 //if the OnPropertyChanged string doesn't match a valid property name, no PropertyDescriptor should be generated
694 persons[0].LastName = "de le Vulu";
695 Assert.IsFalse ((bool) hasPropertyDescriptor, "#2");