PageRenderTime 38ms CodeModel.GetById 26ms app.highlight 8ms RepoModel.GetById 1ms 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
  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
 27using System;
 28using System.Collections;
 29using System.ComponentModel;
 30using System.Reflection;
 31using System.Collections.Generic;
 32
 33namespace System.Windows.Forms
 34{
 35
 36	public static class ListBindingHelper 
 37	{
 38		public static object GetList (object list)
 39		{
 40			if (list is IListSource)
 41				return ((IListSource) list).GetList ();
 42			return list;
 43		}
 44
 45		public static object GetList (object dataSource, string dataMember)
 46		{
 47			dataSource = GetList (dataSource);
 48			if (dataSource == null || dataMember == null || dataMember.Length == 0)
 49				return dataSource;
 50
 51			PropertyDescriptor property = GetListItemProperties (dataSource).Find (dataMember, true);
 52			if (property == null)
 53				throw new ArgumentException ("dataMember");
 54
 55			object item = null;
 56
 57			ICurrencyManagerProvider currencyManagerProvider = dataSource as ICurrencyManagerProvider;
 58			if (currencyManagerProvider != null && currencyManagerProvider.CurrencyManager != null) {
 59				CurrencyManager currencyManager = currencyManagerProvider.CurrencyManager;
 60				if (currencyManager != null && currencyManager.Count > 0 && currencyManager.Current != null)
 61					item = currencyManager.Current;
 62			}
 63
 64			if (item == null) {
 65				if (dataSource is IEnumerable) {
 66					if (dataSource is IList) {
 67						IList list = (IList) dataSource;
 68						item = list.Count > 0 ? list[0] : null;
 69					} else {
 70						IEnumerator e = ((IEnumerable) dataSource).GetEnumerator ();
 71						if (e != null && e.MoveNext ())
 72							item = e.Current;
 73					}
 74				} else {
 75					item = dataSource;
 76				}
 77			}
 78
 79			if (item != null)
 80				return property.GetValue (item);
 81			return null;
 82		}
 83
 84		public static Type GetListItemType (object list)
 85		{
 86			return GetListItemType (list, String.Empty);
 87		}
 88
 89		public static Type GetListItemType (object dataSource, string dataMember)
 90		{
 91			if (dataSource == null)
 92				return null;
 93
 94			if (dataMember != null && dataMember.Length > 0) {
 95				PropertyDescriptor property = GetProperty (dataSource, dataMember);
 96				if (property == null)
 97					return typeof (object);
 98
 99				return property.PropertyType;
100			}
101
102			if (dataSource is Array)
103				return dataSource.GetType ().GetElementType ();
104
105			// IEnumerable seems to have higher precedence over IList
106			if (dataSource is IEnumerable) {
107				IEnumerator enumerator = ((IEnumerable) dataSource).GetEnumerator ();
108				if (enumerator.MoveNext () && enumerator.Current != null)
109					return enumerator.Current.GetType ();
110
111				if (dataSource is IList || dataSource.GetType () == typeof (IList<>)) {
112					PropertyInfo property = GetPropertyByReflection (dataSource.GetType (), "Item");
113					if (property != null) // `Item' could be interface-explicit, and thus private
114						return property.PropertyType;
115				}
116
117				// fallback to object
118				return typeof (object);
119			}
120
121			return dataSource.GetType ();
122		}
123
124		public static PropertyDescriptorCollection GetListItemProperties (object list)
125		{
126			return GetListItemProperties (list, null);
127		}
128
129		public static PropertyDescriptorCollection GetListItemProperties (object list, PropertyDescriptor [] listAccessors)
130		{
131			list = GetList (list);
132
133			if (list == null)
134				return new PropertyDescriptorCollection (null);
135
136			if (list is ITypedList)
137				return ((ITypedList)list).GetItemProperties (listAccessors);
138
139			if (listAccessors == null || listAccessors.Length == 0) {
140				Type item_type = GetListItemType (list);
141				return TypeDescriptor.GetProperties (item_type, 
142					new Attribute [] { new BrowsableAttribute (true) });
143			}
144
145			// Take into account only the first property
146			Type property_type = listAccessors [0].PropertyType;
147			if (typeof (IList).IsAssignableFrom (property_type) || typeof (IList<>).IsAssignableFrom (property_type)) {
148
149				PropertyInfo property = GetPropertyByReflection (property_type, "Item");
150				return TypeDescriptor.GetProperties (property.PropertyType);
151			}
152
153			return new PropertyDescriptorCollection (new PropertyDescriptor [0]);
154		}
155
156		public static PropertyDescriptorCollection GetListItemProperties (object dataSource, string dataMember, 
157			PropertyDescriptor [] listAccessors)
158		{
159			throw new NotImplementedException ();
160		}
161
162		public static string GetListName (object list, PropertyDescriptor [] listAccessors)
163		{
164			if (list == null)
165				return String.Empty;
166
167			Type item_type = GetListItemType (list);
168			return item_type.Name;
169		}
170
171		static PropertyDescriptor GetProperty (object obj, string property_name)
172		{
173			return TypeDescriptor.GetProperties (obj, 
174							     new Attribute [] { new BrowsableAttribute (true) })[property_name];
175		}
176
177		// 
178		// Need to use reflection as we need to bypass the TypeDescriptor.GetProperties () limitations
179		//
180		static PropertyInfo GetPropertyByReflection (Type type, string property_name)
181		{
182			foreach (PropertyInfo prop in type.GetProperties (BindingFlags.Public | BindingFlags.Instance))
183				if (prop.Name == property_name)
184					return prop;
185
186			return null;
187		}
188	}
189}