diff options
Diffstat (limited to 'mcs/class/Managed.Windows.Forms/System.Windows.Forms/CurrencyManager.cs')
-rw-r--r-- | mcs/class/Managed.Windows.Forms/System.Windows.Forms/CurrencyManager.cs | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/CurrencyManager.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/CurrencyManager.cs new file mode 100644 index 00000000000..23a214175fd --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/CurrencyManager.cs @@ -0,0 +1,289 @@ +// 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) 2005 Novell, Inc. +// +// Authors: +// Jackson Harper (jackson@ximian.com) +// + +using System; +using System.Data; +using System.Reflection; +using System.Collections; +using System.ComponentModel; + +namespace System.Windows.Forms { + [DefaultMember("Item")] + public class CurrencyManager : BindingManagerBase { + + protected Type finalType; + protected int listposition; + + private IList list; + private bool binding_suspended; + + internal CurrencyManager (object data_source) + { + if (data_source is IListSource) { + list = ((IListSource) data_source).GetList (); + } else if (data_source is IList) { + list = (IList) data_source; + } else { + throw new Exception ("Attempted to create currency manager " + + "from invalid type: " + data_source.GetType ()); + } + + if (data_source as ArrayList != null) { + finalType = ((ArrayList)data_source).GetType (); + } else { + if (data_source as Array != null) { + finalType = ((Array) data_source).GetType (); + } else { + finalType = null; + } + } + + DataTable table = data_source as DataTable; + if (table == null && data_source is DataView) + table = ((DataView) data_source).Table; + + if (table != null) { + table.Columns.CollectionChanged += new CollectionChangeEventHandler (MetaDataChangedHandler); + table.ChildRelations.CollectionChanged += new CollectionChangeEventHandler (MetaDataChangedHandler); + table.ParentRelations.CollectionChanged += new CollectionChangeEventHandler (MetaDataChangedHandler); + table.Constraints.CollectionChanged += new CollectionChangeEventHandler (MetaDataChangedHandler); + } + } + + public IList List { + get { return list; } + } + + public override object Current { + get { + return list [listposition]; + } + } + + public override int Count { + get { return list.Count; } + } + + public override int Position { + get { + return listposition; + } + set { + if (value < 0) + value = 0; + if (value == list.Count) + value = list.Count - 1; + if (listposition == value) + return; + listposition = value; + OnCurrentChanged (EventArgs.Empty); + OnPositionChanged (EventArgs.Empty); + } + } + + internal string ListName { + get { + ITypedList typed = list as ITypedList; + + if (typed == null) { + return finalType.Name; + } else { + return typed.GetListName (null); + } + } + } + + public override PropertyDescriptorCollection GetItemProperties () + { + ITypedList typed = list as ITypedList; + + if (list is Array) { + Type element = list.GetType ().GetElementType (); + return TypeDescriptor.GetProperties (element); + } + + if (typed != null) { + return typed.GetItemProperties (null); + } + + PropertyInfo [] props = finalType.GetProperties (); + for (int i = 0; i < props.Length; i++) { + if (props [i].Name == "Item") { + Type t = props [i].PropertyType; + if (t == typeof (object)) + continue; + return GetBrowsableProperties (t); + } + } + + if (list.Count > 0) { + return GetBrowsableProperties (list [0].GetType ()); + } + + return new PropertyDescriptorCollection (null); + } + + public override void RemoveAt (int index) + { + list.RemoveAt (index); + } + + public override void SuspendBinding () + { + binding_suspended = true; + } + + public override void ResumeBinding () + { + binding_suspended = false; + } + + internal override bool IsSuspended { + get { return binding_suspended; } + } + + internal bool CanAddRows { + get { + if (list as IBindingList == null) { + return false; + } + + return true; + } + } + + public override void AddNew () + { + if (list as IBindingList == null) + throw new NotSupportedException (); + + (list as IBindingList).AddNew (); + } + + public override void CancelCurrentEdit () + { + IEditableObject editable = Current as IEditableObject; + + if (editable == null) + return; + editable.CancelEdit (); + OnItemChanged (new ItemChangedEventArgs (Position)); + } + + public override void EndCurrentEdit () + { + IEditableObject editable = Current as IEditableObject; + + if (editable == null) + return; + editable.EndEdit (); + } + + public void Refresh () + { + PullData (); + } + + [MonoTODO ("This is just a guess, as I can't figure out how to test this method")] + protected void CheckEmpty () + { + if (list == null || list.Count < 1) + throw new Exception ("List is empty."); + + } + + protected internal override void OnCurrentChanged (EventArgs e) + { + PullData (); + + if (onCurrentChangedHandler != null) { + onCurrentChangedHandler (this, e); + } + } + + protected virtual void OnItemChanged (ItemChangedEventArgs e) + { + PushData (); + + if (ItemChanged != null) + ItemChanged (this, e); + } + + protected virtual void OnPositionChanged (EventArgs e) + { + if (onPositionChangedHandler == null) + return; + onPositionChangedHandler (this, e); + } + + protected internal override string GetListName (ArrayList accessors) + { + if (list is ITypedList) { + PropertyDescriptor [] pds; + pds = new PropertyDescriptor [accessors.Count]; + accessors.CopyTo (pds, 0); + return ((ITypedList) list).GetListName (pds); + } + return String.Empty; + } + + [MonoTODO ("Not totally sure how this works, its doesn't seemt to do a pull/push like i originally assumed")] + protected override void UpdateIsBinding () + { + UpdateItem (); + + foreach (Binding binding in Bindings) + binding.UpdateIsBinding (); + } + + private void UpdateItem () + { + // Probably should be validating or something here + EndCurrentEdit (); + } + + internal object GetItem (int index) + { + return list [index]; + } + + private PropertyDescriptorCollection GetBrowsableProperties (Type t) + { + Attribute [] att = new System.Attribute [1]; + att [0] = new BrowsableAttribute (true); + return TypeDescriptor.GetProperties (t, att); + } + + private void MetaDataChangedHandler (object sender, CollectionChangeEventArgs e) + { + if (MetaDataChanged != null) + MetaDataChanged (this, EventArgs.Empty); + } + + public event ItemChangedEventHandler ItemChanged; + public event EventHandler MetaDataChanged; + } +} + |