diff options
| author | MichaelTheShifter <[email protected]> | 2016-07-20 09:40:36 -0400 |
|---|---|---|
| committer | MichaelTheShifter <[email protected]> | 2016-07-20 09:40:36 -0400 |
| commit | d40fed5ce2bc806a91245adb18039634eac13ed0 (patch) | |
| tree | f1d7168aee6db109ac2c738ad18c9db667a6ba69 /source/ShiftUI/Internal/BindingContext.cs | |
| parent | f1856e8ed30ed882229fd3fa2a4038122a5fb441 (diff) | |
| download | shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.tar.gz shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.tar.bz2 shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.zip | |
Move ShiftUI source code to ShiftOS
This'll be a lot easier to work on.
Diffstat (limited to 'source/ShiftUI/Internal/BindingContext.cs')
| -rw-r--r-- | source/ShiftUI/Internal/BindingContext.cs | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/source/ShiftUI/Internal/BindingContext.cs b/source/ShiftUI/Internal/BindingContext.cs new file mode 100644 index 0000000..fbf461a --- /dev/null +++ b/source/ShiftUI/Internal/BindingContext.cs @@ -0,0 +1,257 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// 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-2005 Novell, Inc. +// +// Authors: +// Peter Bartok [email protected] +// Jackson Harper [email protected] + + +using System.Data; +using System.Collections; +using System.Globalization; +using System.ComponentModel; +using System; + +namespace ShiftUI { + + [DefaultEvent("CollectionChanged")] + public class BindingContext : ICollection, IEnumerable { + + 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 (); + onCollectionChangedHandler = null; + } + + public bool IsReadOnly { + get { return false; } + } + + public BindingManagerBase this [object dataSource] { + get { return this [dataSource, String.Empty]; } + } + + public BindingManagerBase this [object dataSource, string dataMember] { + get { + if (dataSource == null) + throw new ArgumentNullException ("dataSource"); + if (dataMember == null) + dataMember = String.Empty; + + ICurrencyManagerProvider cm_provider = dataSource as ICurrencyManagerProvider; + if (cm_provider != null) { + if (dataMember.Length == 0) + return cm_provider.CurrencyManager; + + return cm_provider.GetRelatedCurrencyManager (dataMember); + } + + 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; + } + } + + 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); + } + } + + 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, 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); + OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataSource)); + } + + 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 () + { + ClearCore(); + OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, null)); + } + + protected virtual void ClearCore () + { + managers.Clear (); + } + + protected virtual void OnCollectionChanged (CollectionChangeEventArgs ccevent) + { + if (onCollectionChangedHandler != null) { + onCollectionChangedHandler (this, ccevent); + } + } + + protected internal void Remove (object dataSource) + { + if (dataSource == null) + throw new ArgumentNullException ("dataSource"); + + RemoveCore (dataSource); + OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Remove, dataSource)); + } + + 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]); + } + } + + [MonoTODO ("Stub, does nothing")] + public static void UpdateBinding (BindingContext newBindingContext, Binding binding) + { + } + + #endregion // Protected Instance Methods + + #region Events + [Browsable (false)] + //[EditorBrowsable (EditorBrowsableState.Never)] + public event CollectionChangeEventHandler CollectionChanged { + add { throw new NotImplementedException (); } + remove { /* nothing to do here.. */ } + } + #endregion // Events + + #region ICollection Interfaces + void ICollection.CopyTo (Array ar, int index) + { + managers.CopyTo (ar, index); + } + + int ICollection.Count { + get { return managers.Count; } + } + + bool ICollection.IsSynchronized { + get { return false; } + } + + object ICollection.SyncRoot { + get { return null; } + } + + #endregion // ICollection Interfaces + + #region IEnumerable Interfaces + [MonoInternalNote ("our enumerator is slightly different. in MS's implementation the Values are WeakReferences to the managers.")] + IEnumerator IEnumerable.GetEnumerator() { + return managers.GetEnumerator (); + } + #endregion // IEnumerable Interfaces + } +} |
