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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
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
48 bool raise_list_changed_events
;
56 public BindingSource (IContainer container
) : this ()
61 public BindingSource (object dataSource
, string dataMember
)
63 datasource
= dataSource
;
64 datamember
= dataMember
;
66 raise_list_changed_events
= true;
71 public BindingSource ()
76 raise_list_changed_events
= true;
81 IList
GetListFromEnumerable (IEnumerable enumerable
)
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> ();
92 /* try to figure out the type based on
93 * the first element, if there is
104 Type t
= typeof (BindingList
<>).MakeGenericType (new Type
[] { first.GetType() }
);
105 l
= (IList
)Activator
.CreateInstance (t
);
110 while (e
.MoveNext ()) {
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
;
133 Type t
= typeof (BindingList
<>).MakeGenericType (new Type
[] { datasource.GetType() }
);
134 l
= (IList
)Activator
.CreateInstance (t
);
140 if (datamember
!= "") {
145 public virtual bool AllowEdit
{
153 if (list
is IBindingList
)
154 return ((IBindingList
)list
).AllowEdit
;
160 public virtual bool AllowNew
{
165 if (list
.IsFixedSize
|| list
.IsReadOnly
)
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
177 if (allow_new
!= value) {
178 allow_new_set
= true;
181 if (raise_list_changed_events
)
182 OnListChanged (new ListChangedEventArgs (ListChangedType
.Reset
, -1));
188 public virtual bool AllowRemove
{
193 if (list
.IsFixedSize
|| list
.IsReadOnly
)
196 if (list
is IBindingList
)
197 return ((IBindingList
)list
).AllowRemove
;
204 public virtual int Count
{
213 public virtual CurrencyManager CurrencyManager
{
214 get { throw new NotImplementedException (); }
218 public object Current
{
219 get { throw new NotImplementedException (); }
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; }
228 /* we don't allow null DataMembers */
232 if (datamember
!= value) {
233 this.datamember
= value;
237 OnDataMemberChanged (EventArgs
.Empty
);
242 [AttributeProvider (typeof(IListSource
))]
243 [RefreshProperties (RefreshProperties
.Repaint
)]
244 [DefaultValue (null)]
245 public object DataSource
{
246 get { return datasource; }
248 if (datasource
!= value) {
249 this.datasource
= value;
256 OnDataSourceChanged (EventArgs
.Empty
);
261 [DefaultValue (null)]
262 public virtual string Filter
{
263 get { throw new NotImplementedException (); }
264 set { throw new NotImplementedException (); }
268 public bool IsBindingSuspended
{
269 get { return suspended; }
273 public virtual bool IsFixedSize
{
274 get { return list.IsFixedSize; }
278 public virtual bool IsReadOnly
{
279 get { return list.IsReadOnly; }
283 public virtual bool IsSorted
{
284 get { return (list is IBindingList) && ((IBindingList)list).IsSorted; }
288 public virtual bool IsSynchronized
{
289 get { throw new NotImplementedException (); }
293 public virtual object this [int index
] {
294 get { throw new NotImplementedException (); }
295 set { throw new NotImplementedException (); }
305 public int Position
{
306 get { return position; }
308 if (value >= Count
) value = Count
- 1;
309 if (value < 0) value = 0;
311 if (position
!= value) {
313 OnPositionChanged (EventArgs
.Empty
);
319 [DefaultValue (true)]
320 public bool RaiseListChangedEvents
{
321 get { return raise_list_changed_events; }
322 set { raise_list_changed_events = value; }
325 [DefaultValue (null)]
327 get { throw new NotImplementedException (); }
328 set { throw new NotImplementedException (); }
332 [EditorBrowsable (EditorBrowsableState
.Never
)]
333 public virtual ListSortDescriptionCollection SortDescriptions
{
335 if (list
is IBindingListView
)
336 return ((IBindingListView
)list
).SortDescriptions
;
343 [EditorBrowsable (EditorBrowsableState
.Never
)]
344 public virtual ListSortDirection SortDirection
{
346 if (list
is IBindingList
)
347 return ((IBindingList
)list
).SortDirection
;
349 return ListSortDirection
.Ascending
;
354 [EditorBrowsable (EditorBrowsableState
.Never
)]
355 public virtual PropertyDescriptor SortProperty
{
357 if (list
is IBindingList
)
358 return ((IBindingList
)list
).SortProperty
;
365 public virtual bool SupportsAdvancedSorting
{
366 get { return (list is IBindingListView) && ((IBindingListView)list).SupportsAdvancedSorting; }
370 public virtual bool SupportsChangeNotification
{
375 public virtual bool SupportsFiltering
{
376 get { return (list is IBindingListView) && ((IBindingListView)list).SupportsFiltering; }
380 public virtual bool SupportsSearching
{
382 return (list
is IBindingList
) && ((IBindingList
)list
).SupportsSearching
;
387 public virtual bool SupportsSorting
{
388 get { return (list is IBindingList) && ((IBindingList)list).SupportsSorting; }
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
||
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 ()
553 public void MoveLast ()
555 Position
= Count
- 1;
558 public void MoveNext ()
563 public void MovePrevious ()
568 protected virtual void OnAddingNew (AddingNewEventArgs e
)
570 AddingNewEventHandler eh
= (AddingNewEventHandler
)Events
[AddingNewEvent
];
575 protected virtual void OnBindingComplete (BindingCompleteEventArgs e
)
577 BindingCompleteEventHandler eh
= (BindingCompleteEventHandler
) Events
[BindingCompleteEvent
];
582 protected virtual void OnCurrentChanged (EventArgs e
)
584 EventHandler eh
= (EventHandler
) Events
[CurrentChangedEvent
];
589 protected virtual void OnCurrentItemChanged (EventArgs e
)
591 EventHandler eh
= (EventHandler
) Events
[CurrentItemChangedEvent
];
596 protected virtual void OnDataError (BindingManagerDataErrorEventArgs e
)
598 BindingManagerDataErrorEventHandler eh
= (BindingManagerDataErrorEventHandler
) Events
[DataErrorEvent
];
603 protected virtual void OnDataMemberChanged (EventArgs e
)
605 EventHandler eh
= (EventHandler
) Events
[DataMemberChangedEvent
];
610 protected virtual void OnDataSourceChanged (EventArgs e
)
612 EventHandler eh
= (EventHandler
) Events
[DataSourceChangedEvent
];
617 protected virtual void OnListChanged (ListChangedEventArgs e
)
619 ListChangedEventHandler eh
= (ListChangedEventHandler
) Events
[ListChangedEvent
];
624 protected virtual void OnPositionChanged (EventArgs e
)
626 EventHandler eh
= (EventHandler
) Events
[PositionChangedEvent
];
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
)
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 ()
683 throw new NotImplementedException ();
686 public void SuspendBinding ()
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
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 ();