WindowsFormsReplacement.BindingSource.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2007 Novell, Inc.
  21. //
  22. // Modified by: Alexander Tzyganenko
  23. using System;
  24. using System.ComponentModel;
  25. using System.Collections;
  26. namespace System.Windows.Forms
  27. {
  28. public class BindingSource : Component, IList, ICollection, IEnumerable
  29. {
  30. IList list;
  31. object datasource;
  32. public object DataSource
  33. {
  34. get { return datasource; }
  35. set
  36. {
  37. if (datasource != value)
  38. {
  39. datasource = value;
  40. ResetList();
  41. }
  42. }
  43. }
  44. public bool IsFixedSize => list.IsFixedSize;
  45. public bool IsReadOnly => list.IsReadOnly;
  46. public int Count => list.Count;
  47. public bool IsSynchronized => list.IsSynchronized;
  48. public object SyncRoot => list.SyncRoot;
  49. public object this[int index] { get => list[index]; set => list[index] = value; }
  50. IList GetListFromEnumerable(IEnumerable enumerable)
  51. {
  52. IList l;
  53. IEnumerator e = enumerable.GetEnumerator();
  54. if (enumerable is string)
  55. {
  56. /* special case this.. seems to be the only one .net special cases? */
  57. l = new BindingList<char>();
  58. }
  59. else
  60. {
  61. /* try to figure out the type based on
  62. * the first element, if there is
  63. * one */
  64. object first = null;
  65. if (e.MoveNext())
  66. {
  67. first = e.Current;
  68. }
  69. if (first == null)
  70. {
  71. return null;
  72. }
  73. else
  74. {
  75. Type t = typeof(BindingList<>).MakeGenericType(new Type[] { first.GetType() });
  76. l = (IList)Activator.CreateInstance(t);
  77. }
  78. }
  79. e.Reset();
  80. while (e.MoveNext())
  81. {
  82. l.Add(e.Current);
  83. }
  84. return l;
  85. }
  86. void ResetList()
  87. {
  88. IList l;
  89. object source = ListBindingHelper.GetList(datasource, null);
  90. //
  91. // If original source is null, then create a new object list
  92. // Otherwise, try to infer the list item type
  93. //
  94. if (datasource == null)
  95. {
  96. l = new BindingList<object>();
  97. }
  98. else if (source == null)
  99. {
  100. //Infer type based on datasource and datamember,
  101. // where datasource is an empty IEnumerable
  102. // and need to find out the datamember type
  103. Type property_type = ListBindingHelper.GetListItemProperties(datasource)[""].PropertyType;
  104. Type t = typeof(BindingList<>).MakeGenericType(new Type[] { property_type });
  105. l = (IList)Activator.CreateInstance(t);
  106. }
  107. else if (source is IList)
  108. {
  109. l = (IList)source;
  110. }
  111. else if (source is IEnumerable)
  112. {
  113. IList new_list = GetListFromEnumerable((IEnumerable)source);
  114. l = new_list == null ? list : new_list;
  115. }
  116. else if (source is Type)
  117. {
  118. Type t = typeof(BindingList<>).MakeGenericType(new Type[] { (Type)source });
  119. l = (IList)Activator.CreateInstance(t);
  120. }
  121. else
  122. {
  123. Type t = typeof(BindingList<>).MakeGenericType(new Type[] { source.GetType() });
  124. l = (IList)Activator.CreateInstance(t);
  125. l.Add(source);
  126. }
  127. list = l;
  128. }
  129. public virtual PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
  130. {
  131. return ListBindingHelper.GetListItemProperties(list, listAccessors);
  132. }
  133. public int Add(object value) => list.Add(value);
  134. public void Clear() => list.Clear();
  135. public bool Contains(object value) => list.Contains(value);
  136. public int IndexOf(object value) => list.IndexOf(value);
  137. public void Insert(int index, object value) => list.Insert(index, value);
  138. public void Remove(object value) => list.Remove(value);
  139. public void RemoveAt(int index) => list.RemoveAt(index);
  140. public void CopyTo(Array array, int index) => list.CopyTo(array, index);
  141. public IEnumerator GetEnumerator() => list.GetEnumerator();
  142. }
  143. }