// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// Copyright (c) 2004 Novell, Inc.
+// Copyright (c) 2004-2005 Novell, Inc.
//
// Authors:
// Peter Bartok pbartok@novell.com
-//
+// Jackson Harper jackson@ximian.com
-// NOT COMPLETE
+using System.Data;
using System.Collections;
+using System.Globalization;
using System.ComponentModel;
+
namespace System.Windows.Forms {
+
+ [DefaultEvent("CollectionChanged")]
public class BindingContext : ICollection, IEnumerable {
- #region Public Constructors
- public BindingContext() {
+
+ private Hashtable managers;
+ private EventHandler onCollectionChangedHandler;
+
+ private class HashKey {
+ public object source;
+ public string member;
+
+ public HashKey (object source, string member)
+ {
+ this.source = source;
+ this.member = member;
+ }
+
+ public override int GetHashCode ()
+ {
+ return source.GetHashCode() ^ member.GetHashCode ();
+ }
+
+ public override bool Equals (object o)
+ {
+ HashKey hk = o as HashKey;
+ if (hk == null)
+ return false;
+ return hk.source == source && hk.member == member;
+ }
+ }
+
+ public BindingContext ()
+ {
+ managers = new Hashtable ();
}
- #endregion // Public Constructors
- #region Public Instance Properties
- [MonoTODO]
public bool IsReadOnly {
- get {
- throw new NotImplementedException();
- }
+ get { return false; }
}
- public BindingManagerBase this[object dataSource] {
+ public BindingManagerBase this [object dataSource] {
+ get { return this [dataSource, String.Empty]; }
+ }
+
+ public BindingManagerBase this [object dataSource, string dataMember] {
get {
- return this[dataSource, String.Empty];
+ if (dataSource == null)
+ throw new ArgumentNullException ("dataSource");
+ if (dataMember == null)
+ dataMember = String.Empty;
+
+ HashKey key = new HashKey (dataSource, dataMember);
+ BindingManagerBase res = managers [key] as BindingManagerBase;
+
+ if (res != null)
+ return res;
+
+ res = CreateBindingManager (dataSource, dataMember);
+ if (res == null)
+ return null;
+ managers [key] = res;
+ return res;
}
}
- [MonoTODO]
- public BindingManagerBase this[object dataSource, string dataMember] {
- get {
- throw new NotImplementedException();
+ private BindingManagerBase CreateBindingManager (object data_source, string data_member)
+ {
+ if (data_member == "") {
+ if (IsListType (data_source.GetType ()))
+ return new CurrencyManager (data_source);
+ else
+ return new PropertyManager (data_source);
+ }
+ else {
+ BindingMemberInfo info = new BindingMemberInfo (data_member);
+
+ BindingManagerBase parent_manager = this[data_source, info.BindingPath];
+
+ PropertyDescriptor pd = parent_manager == null ? null : parent_manager.GetItemProperties ().Find (info.BindingField, true);
+
+ if (pd == null)
+ throw new ArgumentException (String.Format ("Cannot create a child list for field {0}.", info.BindingField));
+
+ if (IsListType (pd.PropertyType))
+ return new RelatedCurrencyManager (parent_manager, pd);
+ else
+ return new RelatedPropertyManager (parent_manager, info.BindingField);
}
}
-
- #endregion // Public Instance Properties
+ bool IsListType (Type t)
+ {
+ return (typeof (IList).IsAssignableFrom (t)
+ || typeof (IListSource).IsAssignableFrom (t));
+ }
#region Public Instance Methods
- public bool Contains(object dataSource) {
- return Contains(dataSource, String.Empty);
+ public bool Contains(object dataSource)
+ {
+ return Contains (dataSource, String.Empty);
}
- [MonoTODO]
- public bool Contains(object dataSource, string dataMember) {
- throw new NotImplementedException();
+ public bool Contains (object dataSource, string dataMember)
+ {
+ if (dataSource == null)
+ throw new ArgumentNullException ("dataSource");
+ if (dataMember == null)
+ dataMember = String.Empty;
+
+ HashKey key = new HashKey (dataSource, dataMember);
+ return managers [key] != null;
}
#endregion // Public Instance Methods
#region Protected Instance Methods
- protected internal void Add(object dataSource, BindingManagerBase listManager) {
- AddCore(dataSource, listManager);
+
+ protected internal void Add (object dataSource, BindingManagerBase listManager)
+ {
+ AddCore (dataSource, listManager);
+ OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataSource));
}
- [MonoTODO]
- protected virtual void AddCore(object dataSource, BindingManagerBase listManager) {
- throw new NotImplementedException();
+ protected virtual void AddCore (object dataSource, BindingManagerBase listManager)
+ {
+ if (dataSource == null)
+ throw new ArgumentNullException ("dataSource");
+ if (listManager == null)
+ throw new ArgumentNullException ("listManager");
+
+ HashKey key = new HashKey (dataSource, String.Empty);
+ managers [key] = listManager;
}
- protected internal void Clear() {
+ protected internal void Clear ()
+ {
ClearCore();
+ OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, null));
}
- [MonoTODO]
- protected virtual void ClearCore() {
- throw new NotImplementedException();
+ protected virtual void ClearCore ()
+ {
+ managers.Clear ();
}
- protected virtual void OnCollectionChanged(System.ComponentModel.CollectionChangeEventArgs ccevent) {
- if (CollectionChanged!=null) CollectionChanged(this, ccevent);
+ protected virtual void OnCollectionChanged (CollectionChangeEventArgs ccevent)
+ {
+ if (onCollectionChangedHandler != null) {
+ onCollectionChangedHandler (this, ccevent);
+ }
}
- protected internal void Remove(object dataSource) {
- RemoveCore(dataSource);
+ protected internal void Remove (object dataSource)
+ {
+ if (dataSource == null)
+ throw new ArgumentNullException ("dataSource");
+
+ RemoveCore (dataSource);
+ OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Remove, dataSource));
}
- [MonoTODO]
- protected virtual void RemoveCore(object dataSource) {
- throw new NotImplementedException();
+ protected virtual void RemoveCore (object dataSource)
+ {
+ HashKey[] keys = new HashKey [managers.Keys.Count];
+ managers.Keys.CopyTo (keys, 0);
+
+ for (int i = 0; i < keys.Length; i ++) {
+ if (keys[i].source == dataSource)
+ managers.Remove (keys[i]);
+ }
}
#endregion // Protected Instance Methods
#region Events
- public event CollectionChangeEventHandler CollectionChanged;
+#if NET_2_0
+ [Browsable (false)]
+ [EditorBrowsable (EditorBrowsableState.Never)]
+#endif
+ public event CollectionChangeEventHandler CollectionChanged {
+ add { throw new NotImplementedException (); }
+ remove { /* nothing to do here.. */ }
+ }
#endregion // Events
#region ICollection Interfaces
- [MonoTODO]
- void ICollection.CopyTo(Array array, int index) {
- throw new NotImplementedException();
+ void ICollection.CopyTo (Array array, int index)
+ {
+ managers.CopyTo (array, index);
}
- [MonoTODO]
int ICollection.Count {
- get {
- throw new NotImplementedException();
- }
+ get { return managers.Count; }
}
bool ICollection.IsSynchronized {
- get {
- return false;
- }
+ get { return false; }
}
object ICollection.SyncRoot {
- get {
- return this;
- }
+ get { return null; }
}
#endregion // ICollection Interfaces
#region IEnumerable Interfaces
- [MonoTODO]
+ [MonoTODO ("our enumerator is slightly different. in MS's implementation the Values are WeakReferences to the managers.")]
IEnumerator IEnumerable.GetEnumerator() {
- throw new NotImplementedException();
+ return managers.GetEnumerator ();
}
#endregion // IEnumerable Interfaces
}