merge -r 60439:60440
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / BindingContext.cs
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.
19 //
20 // Copyright (c) 2004-2005 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //      Jackson Harper  jackson@ximian.com
25
26
27 using System.Collections;
28 using System.Globalization;
29 using System.ComponentModel;
30
31
32 namespace System.Windows.Forms {
33
34         [DefaultEvent("CollectionChanged")]
35         public class BindingContext : ICollection, IEnumerable {
36
37                 private Hashtable managers;
38                 private object null_data_source = new object ();
39
40                 private class DataSourceEntry {
41
42                         private object source;
43                         private Hashtable members;
44                         // private BindingManagerBase default_manager;
45                         
46                         public DataSourceEntry (object source)
47                         {
48                                 this.source = source;
49                                 members = new Hashtable ();
50                         }
51
52                         public BindingManagerBase AddMember (string member)
53                         {
54                                 if (member == null)
55                                         member = String.Empty;
56                                 BindingManagerBase res = members [member] as BindingManagerBase;
57                                 if (res != null)
58                                         return res;
59                                 res = CreateBindingManager (source, member);
60                                 members [member] = res;
61                                 return res;
62                         }
63
64                         public void AddMember (string member, BindingManagerBase manager)
65                         {
66                                 members [member] = manager;
67                         }
68
69                         public bool Contains (string member)
70                         {
71                                 return members.Contains (member);
72                         }
73                 }
74
75                 public BindingContext () 
76                 {
77                         managers = new Hashtable ();
78                 }
79
80                 public bool IsReadOnly {
81                         get {
82                                 return false;
83                         }
84                 }
85
86                 public BindingManagerBase this [object dataSource] {
87                         get {
88                                 return this [dataSource, String.Empty];
89                         }
90                 }
91
92                 public BindingManagerBase this [object data_source, string data_member] {
93                         get {
94                                 DataSourceEntry ds = GetEntry (data_source, data_member, true);
95                                 return ds.AddMember (data_member);
96                         }
97                 }
98
99                 private DataSourceEntry GetEntry (object data_source, string data_member, bool create)
100                 {
101                         if (data_source == null)
102                                 data_source = null_data_source;
103                                 
104                         DataSourceEntry ds = managers [data_source] as DataSourceEntry;
105                         if (ds == null && create) {
106                                 ds = new DataSourceEntry (data_source);
107                                 managers [data_source] = ds;
108                         }
109
110                         return ds;
111                 }
112
113                 private static BindingManagerBase CreateBindingManager (object data_source, 
114                         string data_member)
115                 {
116                         if (data_source is IList || 
117                                 data_source is IListSource ||
118                                 data_source is IBindingList) {
119                                 CurrencyManager res = new CurrencyManager (data_source, data_member);
120                                 return res;
121                         }
122
123                         return new PropertyManager (data_source, data_member);
124                 }
125
126                 #region Public Instance Methods
127                 public bool Contains(object dataSource)
128                 {
129                         return Contains (dataSource, String.Empty);
130                 }
131
132                 public bool Contains (object dataSource, string dataMember)
133                 {
134                         DataSourceEntry ds = GetEntry (dataSource, dataMember, false);
135                         if (ds == null)
136                                 return false;
137                         return ds.Contains (dataMember);
138
139                 }
140                 #endregion      // Public Instance Methods
141
142                 #region Protected Instance Methods
143
144                 protected internal void Add (object dataSource, BindingManagerBase listManager)
145                 {
146                         AddCore (dataSource, listManager);
147                         OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataSource));
148                 }
149
150                 protected virtual void AddCore (object dataSource, BindingManagerBase listManager)
151                 {
152                         if (dataSource == null)
153                                 throw new ArgumentNullException ("dataSource");
154                         if (listManager == null)
155                                 throw new ArgumentNullException ("listManager");
156                         DataSourceEntry ds = GetEntry (dataSource, String.Empty, true);
157                         ds.AddMember (String.Empty, listManager);
158                 }
159
160                 protected internal void Clear ()
161                 {
162                         ClearCore();
163                         OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Refresh, null));
164                 }
165
166                 protected virtual void ClearCore ()
167                 {
168                         managers.Clear ();
169                 }
170
171                 protected virtual void OnCollectionChanged(System.ComponentModel.CollectionChangeEventArgs ccevent)
172                 {
173                         if (CollectionChanged != null) {
174                                 CollectionChanged (this, ccevent);
175                         }
176                 }
177
178                 protected internal void Remove (object dataSource)
179                 {
180                         RemoveCore (dataSource);
181                         OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Remove, dataSource));
182                 }
183
184                 protected virtual void RemoveCore (object dataSource)
185                 {
186                         managers.Remove (dataSource);
187                 }
188                 #endregion      // Protected Instance Methods
189
190                 #region Events
191                 public event CollectionChangeEventHandler CollectionChanged;
192                 #endregion      // Events
193
194                 #region ICollection Interfaces
195                 void ICollection.CopyTo (Array array, int index)
196                 {
197                         managers.CopyTo (array, index);
198                 }
199
200                 int ICollection.Count {
201                         get {
202                                 return managers.Count;
203                         }
204                 }
205
206                 bool ICollection.IsSynchronized {
207                         get {
208                                 return false;
209                         }
210                 }
211
212                 object ICollection.SyncRoot {
213                         get {
214                                 return null;
215                         }
216                 }
217
218                 #endregion      // ICollection Interfaces
219
220                 #region IEnumerable Interfaces
221                 [MonoTODO]
222                 IEnumerator IEnumerable.GetEnumerator() {
223                         throw new NotImplementedException();
224                 }
225                 #endregion      // IEnumerable Interfaces
226         }
227 }