PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListBindingHelper.cs

https://bitbucket.org/danipen/mono
C# | 189 lines | 126 code | 32 blank | 31 comment | 59 complexity | 969ce9bde603856c952856e4cd543264 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  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. // Author:
  23. // Carlos Alberto Cortez <calberto.cortez@gmail.com>
  24. // Ivan Zlatev <contact@i-nz.net>
  25. //
  26. using System;
  27. using System.Collections;
  28. using System.ComponentModel;
  29. using System.Reflection;
  30. using System.Collections.Generic;
  31. namespace System.Windows.Forms
  32. {
  33. public static class ListBindingHelper
  34. {
  35. public static object GetList (object list)
  36. {
  37. if (list is IListSource)
  38. return ((IListSource) list).GetList ();
  39. return list;
  40. }
  41. public static object GetList (object dataSource, string dataMember)
  42. {
  43. dataSource = GetList (dataSource);
  44. if (dataSource == null || dataMember == null || dataMember.Length == 0)
  45. return dataSource;
  46. PropertyDescriptor property = GetListItemProperties (dataSource).Find (dataMember, true);
  47. if (property == null)
  48. throw new ArgumentException ("dataMember");
  49. object item = null;
  50. ICurrencyManagerProvider currencyManagerProvider = dataSource as ICurrencyManagerProvider;
  51. if (currencyManagerProvider != null && currencyManagerProvider.CurrencyManager != null) {
  52. CurrencyManager currencyManager = currencyManagerProvider.CurrencyManager;
  53. if (currencyManager != null && currencyManager.Count > 0 && currencyManager.Current != null)
  54. item = currencyManager.Current;
  55. }
  56. if (item == null) {
  57. if (dataSource is IEnumerable) {
  58. if (dataSource is IList) {
  59. IList list = (IList) dataSource;
  60. item = list.Count > 0 ? list[0] : null;
  61. } else {
  62. IEnumerator e = ((IEnumerable) dataSource).GetEnumerator ();
  63. if (e != null && e.MoveNext ())
  64. item = e.Current;
  65. }
  66. } else {
  67. item = dataSource;
  68. }
  69. }
  70. if (item != null)
  71. return property.GetValue (item);
  72. return null;
  73. }
  74. public static Type GetListItemType (object list)
  75. {
  76. return GetListItemType (list, String.Empty);
  77. }
  78. public static Type GetListItemType (object dataSource, string dataMember)
  79. {
  80. if (dataSource == null)
  81. return null;
  82. if (dataMember != null && dataMember.Length > 0) {
  83. PropertyDescriptor property = GetProperty (dataSource, dataMember);
  84. if (property == null)
  85. return typeof (object);
  86. return property.PropertyType;
  87. }
  88. if (dataSource is Array)
  89. return dataSource.GetType ().GetElementType ();
  90. // IEnumerable seems to have higher precedence over IList
  91. if (dataSource is IEnumerable) {
  92. IEnumerator enumerator = ((IEnumerable) dataSource).GetEnumerator ();
  93. if (enumerator.MoveNext () && enumerator.Current != null)
  94. return enumerator.Current.GetType ();
  95. if (dataSource is IList || dataSource.GetType () == typeof (IList<>)) {
  96. PropertyInfo property = GetPropertyByReflection (dataSource.GetType (), "Item");
  97. if (property != null) // `Item' could be interface-explicit, and thus private
  98. return property.PropertyType;
  99. }
  100. // fallback to object
  101. return typeof (object);
  102. }
  103. return dataSource.GetType ();
  104. }
  105. public static PropertyDescriptorCollection GetListItemProperties (object list)
  106. {
  107. return GetListItemProperties (list, null);
  108. }
  109. public static PropertyDescriptorCollection GetListItemProperties (object list, PropertyDescriptor [] listAccessors)
  110. {
  111. list = GetList (list);
  112. if (list == null)
  113. return new PropertyDescriptorCollection (null);
  114. if (list is ITypedList)
  115. return ((ITypedList)list).GetItemProperties (listAccessors);
  116. if (listAccessors == null || listAccessors.Length == 0) {
  117. Type item_type = GetListItemType (list);
  118. return TypeDescriptor.GetProperties (item_type,
  119. new Attribute [] { new BrowsableAttribute (true) });
  120. }
  121. // Take into account only the first property
  122. Type property_type = listAccessors [0].PropertyType;
  123. if (typeof (IList).IsAssignableFrom (property_type) || typeof (IList<>).IsAssignableFrom (property_type)) {
  124. PropertyInfo property = GetPropertyByReflection (property_type, "Item");
  125. return TypeDescriptor.GetProperties (property.PropertyType);
  126. }
  127. return new PropertyDescriptorCollection (new PropertyDescriptor [0]);
  128. }
  129. public static PropertyDescriptorCollection GetListItemProperties (object dataSource, string dataMember,
  130. PropertyDescriptor [] listAccessors)
  131. {
  132. throw new NotImplementedException ();
  133. }
  134. public static string GetListName (object list, PropertyDescriptor [] listAccessors)
  135. {
  136. if (list == null)
  137. return String.Empty;
  138. Type item_type = GetListItemType (list);
  139. return item_type.Name;
  140. }
  141. static PropertyDescriptor GetProperty (object obj, string property_name)
  142. {
  143. return TypeDescriptor.GetProperties (obj,
  144. new Attribute [] { new BrowsableAttribute (true) })[property_name];
  145. }
  146. //
  147. // Need to use reflection as we need to bypass the TypeDescriptor.GetProperties () limitations
  148. //
  149. static PropertyInfo GetPropertyByReflection (Type type, string property_name)
  150. {
  151. foreach (PropertyInfo prop in type.GetProperties (BindingFlags.Public | BindingFlags.Instance))
  152. if (prop.Name == property_name)
  153. return prop;
  154. return null;
  155. }
  156. }
  157. }