In Test/System.Windows.Forms:
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / BindingSource.cs
blob658a68bb429cfc101d820abdcefe34960d11d003
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.
20 // Copyright (c) 2007 Novell, Inc.
23 #if NET_2_0
25 using System.ComponentModel;
26 using System.Collections;
27 using System.Collections.Generic;
28 using System.Reflection;
30 namespace System.Windows.Forms {
32 [ComplexBindingProperties ("DataSource", "DataMember")]
33 [DefaultEvent ("CurrentChanged")]
34 [DefaultProperty ("DataSource")]
35 [Designer("System.Windows.Forms.Design.BindingSourceDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
36 public class BindingSource : Component,
37 ICancelAddNew, IDisposable, ISupportInitialize,
38 IBindingListView, IBindingList, ITypedList,
39 IList, ISupportInitializeNotification, ICollection,
40 IComponent, ICurrencyManagerProvider, IEnumerable
42 IList list;
43 bool list_defaulted;
45 object datasource;
46 string datamember;
48 bool raise_list_changed_events;
50 bool allow_new_set;
51 bool allow_new;
52 bool suspended;
54 int position = -1;
56 public BindingSource (IContainer container) : this ()
58 container.Add (this);
61 public BindingSource (object dataSource, string dataMember)
63 datasource = dataSource;
64 datamember = dataMember;
66 raise_list_changed_events = true;
68 ResetList ();
71 public BindingSource ()
73 datasource = null;
74 datamember = "";
76 raise_list_changed_events = true;
78 ResetList ();
81 IList GetListFromEnumerable (IEnumerable enumerable)
83 IList l = null;
85 IEnumerator e = enumerable.GetEnumerator();
87 if (enumerable is string) {
88 /* special case this.. seems to be the only one .net special cases? */
89 l = new BindingList<char> ();
91 else {
92 /* try to figure out the type based on
93 * the first element, if there is
94 * one */
95 object first = null;
96 if (e.MoveNext ()) {
97 first = e.Current;
100 if (first == null) {
101 return null;
103 else {
104 Type t = typeof (BindingList<>).MakeGenericType (new Type[] { first.GetType() });
105 l = (IList)Activator.CreateInstance (t);
109 e.Reset ();
110 while (e.MoveNext ()) {
111 l.Add (e.Current);
114 return l;
117 void ResetList ()
119 IList l;
121 if (datasource == null) {
122 l = new BindingList<object>();
123 list_defaulted = true;
125 else if (datasource is IList) {
126 l = (IList)datasource;
128 else if (datasource is IEnumerable) {
129 IList new_list = GetListFromEnumerable ((IEnumerable)datasource);
130 l = new_list == null ? list : new_list;
132 else {
133 Type t = typeof (BindingList<>).MakeGenericType (new Type[] { datasource.GetType() });
134 l = (IList)Activator.CreateInstance (t);
137 // XXX
138 list = l;
140 if (datamember != "") {
144 [Browsable (false)]
145 public virtual bool AllowEdit {
146 get {
147 if (list == null)
148 return false;
150 if (list.IsReadOnly)
151 return false;
153 if (list is IBindingList)
154 return ((IBindingList)list).AllowEdit;
156 return true;
160 public virtual bool AllowNew {
161 get {
162 if (allow_new_set)
163 return allow_new;
165 if (list.IsFixedSize || list.IsReadOnly)
166 return false;
168 if (list is IBindingList)
169 return ((IBindingList)list).AllowNew;
171 // XXX we need to check the element
172 // type to see if it has a default
173 // constructor
174 return true;
176 set {
177 if (allow_new != value) {
178 allow_new_set = true;
179 allow_new = value;
181 if (raise_list_changed_events)
182 OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, -1));
187 [Browsable (false)]
188 public virtual bool AllowRemove {
189 get {
190 if (list == null)
191 return false;
193 if (list.IsFixedSize || list.IsReadOnly)
194 return false;
196 if (list is IBindingList)
197 return ((IBindingList)list).AllowRemove;
199 return true;
203 [Browsable (false)]
204 public virtual int Count {
205 get {
206 if (list == null)
207 return -1;
208 return list.Count;
212 [Browsable (false)]
213 public virtual CurrencyManager CurrencyManager {
214 get { throw new NotImplementedException (); }
217 [Browsable (false)]
218 public object Current {
219 get { throw new NotImplementedException (); }
222 [DefaultValue ("")]
223 [Editor("System.Windows.Forms.Design.DataMemberListEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
224 [RefreshProperties (RefreshProperties.Repaint)]
225 public string DataMember {
226 get { return datamember; }
227 set {
228 /* we don't allow null DataMembers */
229 if (value == null)
230 value = "";
232 if (datamember != value) {
233 this.datamember = value;
235 ResetList ();
237 OnDataMemberChanged (EventArgs.Empty);
242 [AttributeProvider (typeof(IListSource))]
243 [RefreshProperties (RefreshProperties.Repaint)]
244 [DefaultValue (null)]
245 public object DataSource {
246 get { return datasource; }
247 set {
248 if (datasource != value) {
249 this.datasource = value;
250 datamember = "";
252 ResetList ();
254 position = 0;
256 OnDataSourceChanged (EventArgs.Empty);
261 [DefaultValue (null)]
262 public virtual string Filter {
263 get { throw new NotImplementedException (); }
264 set { throw new NotImplementedException (); }
267 [Browsable (false)]
268 public bool IsBindingSuspended {
269 get { return suspended; }
272 [Browsable (false)]
273 public virtual bool IsFixedSize {
274 get { return list.IsFixedSize; }
277 [Browsable (false)]
278 public virtual bool IsReadOnly {
279 get { return list.IsReadOnly; }
282 [Browsable (false)]
283 public virtual bool IsSorted {
284 get { return (list is IBindingList) && ((IBindingList)list).IsSorted; }
287 [Browsable (false)]
288 public virtual bool IsSynchronized {
289 get { throw new NotImplementedException (); }
292 [Browsable (false)]
293 public virtual object this [int index] {
294 get { throw new NotImplementedException (); }
295 set { throw new NotImplementedException (); }
298 [Browsable (false)]
299 public IList List {
300 get { return list; }
303 [DefaultValue (-1)]
304 [Browsable (false)]
305 public int Position {
306 get { return position; }
307 set {
308 if (value >= Count) value = Count - 1;
309 if (value < 0) value = 0;
311 if (position != value) {
312 position = value;
313 OnPositionChanged (EventArgs.Empty);
318 [Browsable (false)]
319 [DefaultValue (true)]
320 public bool RaiseListChangedEvents {
321 get { return raise_list_changed_events; }
322 set { raise_list_changed_events = value; }
325 [DefaultValue (null)]
326 public string Sort {
327 get { throw new NotImplementedException (); }
328 set { throw new NotImplementedException (); }
331 [Browsable (false)]
332 [EditorBrowsable (EditorBrowsableState.Never)]
333 public virtual ListSortDescriptionCollection SortDescriptions {
334 get {
335 if (list is IBindingListView)
336 return ((IBindingListView)list).SortDescriptions;
338 return null;
342 [Browsable (false)]
343 [EditorBrowsable (EditorBrowsableState.Never)]
344 public virtual ListSortDirection SortDirection {
345 get {
346 if (list is IBindingList)
347 return ((IBindingList)list).SortDirection;
349 return ListSortDirection.Ascending;
353 [Browsable (false)]
354 [EditorBrowsable (EditorBrowsableState.Never)]
355 public virtual PropertyDescriptor SortProperty {
356 get {
357 if (list is IBindingList)
358 return ((IBindingList)list).SortProperty;
360 return null;
364 [Browsable (false)]
365 public virtual bool SupportsAdvancedSorting {
366 get { return (list is IBindingListView) && ((IBindingListView)list).SupportsAdvancedSorting; }
369 [Browsable (false)]
370 public virtual bool SupportsChangeNotification {
371 get { return true; }
374 [Browsable (false)]
375 public virtual bool SupportsFiltering {
376 get { return (list is IBindingListView) && ((IBindingListView)list).SupportsFiltering; }
379 [Browsable (false)]
380 public virtual bool SupportsSearching {
381 get {
382 return (list is IBindingList) && ((IBindingList)list).SupportsSearching;
386 [Browsable (false)]
387 public virtual bool SupportsSorting {
388 get { return (list is IBindingList) && ((IBindingList)list).SupportsSorting; }
391 [Browsable (false)]
392 public virtual object SyncRoot {
393 get { throw new NotImplementedException (); }
396 static object AddingNewEvent = new object ();
397 static object BindingCompleteEvent = new object ();
398 static object CurrentChangedEvent = new object ();
399 static object CurrentItemChangedEvent = new object ();
400 static object DataErrorEvent = new object ();
401 static object DataMemberChangedEvent = new object ();
402 static object DataSourceChangedEvent = new object ();
403 static object ListChangedEvent = new object ();
404 static object PositionChangedEvent= new object ();
406 public event AddingNewEventHandler AddingNew {
407 add { Events.AddHandler (AddingNewEvent, value); }
408 remove { Events.RemoveHandler (AddingNewEvent, value); }
411 public event BindingCompleteEventHandler BindingComplete {
412 add { Events.AddHandler (BindingCompleteEvent, value); }
413 remove { Events.RemoveHandler (BindingCompleteEvent, value); }
416 public event EventHandler CurrentChanged {
417 add { Events.AddHandler (CurrentChangedEvent, value); }
418 remove { Events.RemoveHandler (CurrentChangedEvent, value); }
421 public event EventHandler CurrentItemChanged {
422 add { Events.AddHandler (CurrentItemChangedEvent, value); }
423 remove { Events.RemoveHandler (CurrentItemChangedEvent, value); }
426 public event BindingManagerDataErrorEventHandler DataError {
427 add { Events.AddHandler (DataErrorEvent, value); }
428 remove { Events.RemoveHandler (DataErrorEvent, value); }
431 public event EventHandler DataMemberChanged {
432 add { Events.AddHandler (DataMemberChangedEvent, value); }
433 remove { Events.RemoveHandler (DataMemberChangedEvent, value); }
436 public event EventHandler DataSourceChanged {
437 add { Events.AddHandler (DataSourceChangedEvent, value); }
438 remove { Events.RemoveHandler (DataSourceChangedEvent, value); }
441 public event ListChangedEventHandler ListChanged {
442 add { Events.AddHandler (ListChangedEvent, value); }
443 remove { Events.RemoveHandler (ListChangedEvent, value); }
446 public event EventHandler PositionChanged {
447 add { Events.AddHandler (PositionChangedEvent, value); }
448 remove { Events.RemoveHandler (PositionChangedEvent, value); }
451 public virtual int Add (object value)
453 throw new NotImplementedException ();
456 public virtual object AddNew ()
458 if (list.IsFixedSize ||
459 list.IsReadOnly ||
460 (list is IBindingList && !((IBindingList)list).AllowNew))
461 throw new InvalidOperationException ("Item cannot be added to a read-onlyor fixed-size list.");
463 throw new NotImplementedException ();
466 [EditorBrowsable (EditorBrowsableState.Never)]
467 public virtual void ApplySort (PropertyDescriptor property, ListSortDirection sort)
469 throw new NotImplementedException ();
472 [EditorBrowsable (EditorBrowsableState.Never)]
473 public virtual void ApplySort (ListSortDescriptionCollection sorts)
475 throw new NotImplementedException ();
478 public void CancelEdit ()
480 throw new NotImplementedException ();
483 public virtual void Clear ()
485 throw new NotImplementedException ();
488 public virtual bool Contains (object value)
490 throw new NotImplementedException ();
493 public virtual void CopyTo (Array arr, int index)
495 throw new NotImplementedException ();
498 protected virtual void Dispose (bool disposing)
500 throw new NotImplementedException ();
503 public void EndEdit ()
505 throw new NotImplementedException ();
508 public int Find (string propertyName, object key)
510 throw new NotImplementedException ();
513 public virtual int Find (PropertyDescriptor prop, object key)
515 throw new NotImplementedException ();
518 public virtual IEnumerator GetEnumerator ()
520 throw new NotImplementedException ();
523 public virtual PropertyDescriptorCollection GetItemProperties (PropertyDescriptor[] listAccessors)
525 throw new NotImplementedException ();
528 public virtual string GetListName (PropertyDescriptor[] listAccessors)
530 throw new NotImplementedException ();
533 public virtual CurrencyManager GetRelatedCurrencyManager (string dataMamber)
535 throw new NotImplementedException ();
538 public virtual int IndexOf (object value)
540 throw new NotImplementedException ();
543 public virtual void Insert (int index, object value)
545 throw new NotImplementedException ();
548 public void MoveFirst ()
550 Position = 0;
553 public void MoveLast ()
555 Position = Count - 1;
558 public void MoveNext ()
560 Position ++;
563 public void MovePrevious ()
565 Position --;
568 protected virtual void OnAddingNew (AddingNewEventArgs e)
570 AddingNewEventHandler eh = (AddingNewEventHandler)Events[AddingNewEvent];
571 if (eh != null)
572 eh (this, e);
575 protected virtual void OnBindingComplete (BindingCompleteEventArgs e)
577 BindingCompleteEventHandler eh = (BindingCompleteEventHandler) Events[BindingCompleteEvent];
578 if (eh != null)
579 eh (this, e);
582 protected virtual void OnCurrentChanged (EventArgs e)
584 EventHandler eh = (EventHandler) Events[CurrentChangedEvent];
585 if (eh != null)
586 eh (this, e);
589 protected virtual void OnCurrentItemChanged (EventArgs e)
591 EventHandler eh = (EventHandler) Events[CurrentItemChangedEvent];
592 if (eh != null)
593 eh (this, e);
596 protected virtual void OnDataError (BindingManagerDataErrorEventArgs e)
598 BindingManagerDataErrorEventHandler eh = (BindingManagerDataErrorEventHandler) Events[DataErrorEvent];
599 if (eh != null)
600 eh (this, e);
603 protected virtual void OnDataMemberChanged (EventArgs e)
605 EventHandler eh = (EventHandler) Events[DataMemberChangedEvent];
606 if (eh != null)
607 eh (this, e);
610 protected virtual void OnDataSourceChanged (EventArgs e)
612 EventHandler eh = (EventHandler) Events[DataSourceChangedEvent];
613 if (eh != null)
614 eh (this, e);
617 protected virtual void OnListChanged (ListChangedEventArgs e)
619 ListChangedEventHandler eh = (ListChangedEventHandler) Events[ListChangedEvent];
620 if (eh != null)
621 eh (this, e);
624 protected virtual void OnPositionChanged (EventArgs e)
626 EventHandler eh = (EventHandler) Events[PositionChangedEvent];
627 if (eh != null)
628 eh (this, e);
631 public virtual void Remove (object value)
633 throw new NotImplementedException ();
636 public virtual void RemoveAt (int index)
638 throw new NotImplementedException ();
641 public void RemoveCurrent ()
643 throw new NotImplementedException ();
646 public virtual void RemoveFilter ()
648 throw new NotImplementedException ();
651 public virtual void RemoveSort ()
653 throw new NotImplementedException ();
656 [EditorBrowsable (EditorBrowsableState.Advanced)]
657 public virtual void ResetAllowNew ()
659 allow_new_set = false;
662 public void ResetBindings (bool metadataChanged)
664 if (metadataChanged)
665 OnListChanged (new ListChangedEventArgs (ListChangedType.PropertyDescriptorChanged, 0));
667 OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, -1, -1));
670 public void ResetCurrentItem ()
672 OnListChanged (new ListChangedEventArgs (ListChangedType.ItemChanged, Position, -1));
675 public void ResetItem (int itemIndex)
677 OnListChanged (new ListChangedEventArgs (ListChangedType.ItemChanged, itemIndex, -1));
680 public void ResumeBinding ()
682 suspended = false;
683 throw new NotImplementedException ();
686 public void SuspendBinding ()
688 suspended = true;
689 throw new NotImplementedException ();
692 /* explicit interface implementations */
694 void ICancelAddNew.CancelNew (int itemIndex)
696 throw new NotImplementedException ();
699 void ICancelAddNew.EndNew (int itemIndex)
701 throw new NotImplementedException ();
704 void ISupportInitialize.BeginInit ()
706 throw new NotImplementedException ();
709 void ISupportInitialize.EndInit ()
711 throw new NotImplementedException ();
714 void IBindingList.AddIndex (PropertyDescriptor property)
716 if (!(list is IBindingList))
717 throw new NotSupportedException();
719 ((IBindingList)list).AddIndex (property);
722 void IBindingList.RemoveIndex (PropertyDescriptor property)
724 if (!(list is IBindingList))
725 throw new NotSupportedException();
727 ((IBindingList)list).RemoveIndex (property);
730 bool ISupportInitializeNotification.IsInitialized {
731 // XXX this is likely wrong, but i can't
732 // figure out how to make it return false
733 get { return true; }
736 static object InitializedEvent = new object ();
738 event EventHandler ISupportInitializeNotification.Initialized {
739 add { Events.AddHandler (InitializedEvent, value); }
740 remove { Events.RemoveHandler (InitializedEvent, value); }
743 ISite IComponent.Site {
744 get { throw new NotImplementedException (); }
745 set { throw new NotImplementedException (); }
748 event EventHandler IComponent.Disposed {
749 add { throw new NotImplementedException (); }
750 remove { throw new NotImplementedException (); }
753 void IDisposable.Dispose ()
755 throw new NotImplementedException ();
761 #endif