Mercurial > pub > bltoolkit
comparison Source/ComponentModel/ObjectBinder.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
1 using System; | |
2 using System.Collections; | |
3 using System.ComponentModel; | |
4 using System.Drawing.Design; | |
5 using System.Drawing; | |
6 using System.Windows.Forms; | |
7 | |
8 using BLToolkit.EditableObjects; | |
9 using BLToolkit.Reflection; | |
10 | |
11 namespace BLToolkit.ComponentModel | |
12 { | |
13 /// <summary> | |
14 /// http://www.bltoolkit.net/Doc/ComponentModel/ObjectBinder.htm | |
15 /// </summary> | |
16 //[ComplexBindingProperties("DataSource", "DataMember")] | |
17 [ComplexBindingProperties("DataSource")] | |
18 [DefaultProperty("ItemType")] | |
19 [ToolboxItem(true)] | |
20 [ToolboxBitmap(typeof(ObjectBinder))] | |
21 public class ObjectBinder : Component, ITypedList, IBindingListView, ICancelAddNew | |
22 { | |
23 #region Constructors | |
24 | |
25 static readonly EditableArrayList _empty = new EditableArrayList(typeof(object)); | |
26 | |
27 public ObjectBinder() | |
28 { | |
29 } | |
30 | |
31 public ObjectBinder(IContainer container) | |
32 : this() | |
33 { | |
34 if (container != null) | |
35 container.Add(this); | |
36 } | |
37 | |
38 #endregion | |
39 | |
40 #region Public members | |
41 | |
42 private object _dataSource; | |
43 | |
44 [AttributeProvider(typeof(IListSource))] | |
45 [RefreshProperties(RefreshProperties.Repaint)] | |
46 [DefaultValue(null)] | |
47 [Category("Data")] | |
48 public object DataSource | |
49 { | |
50 get { return _dataSource; } | |
51 set | |
52 { | |
53 _dataSource = value; | |
54 | |
55 if (value is Type) ItemType = (Type)value; | |
56 else if (value is BindingSource) DataSource = ((BindingSource)value).DataSource; | |
57 else if (value is IList) List = (IList)value; | |
58 else if (value is IListSource) List = ((IListSource)value).GetList(); | |
59 else Object = value; | |
60 } | |
61 } | |
62 | |
63 private Type _itemType; | |
64 [RefreshProperties(RefreshProperties.Repaint)] | |
65 [DefaultValue(null)] | |
66 [Category("Data")] | |
67 [TypeConverter(typeof(TypeTypeConverter))] | |
68 #if !CLIENTPROFILE | |
69 [Editor(typeof(Design.TypeEditor), typeof(UITypeEditor))] | |
70 #endif | |
71 public Type ItemType | |
72 { | |
73 get { return _itemType; } | |
74 set | |
75 { | |
76 _itemType = value; | |
77 | |
78 List = null; | |
79 | |
80 OnListChanged(ListChangedType.PropertyDescriptorChanged, -1); | |
81 } | |
82 } | |
83 | |
84 private Type _objectViewType; | |
85 [RefreshProperties(RefreshProperties.Repaint)] | |
86 [DefaultValue(null)] | |
87 [Category("Data")] | |
88 [TypeConverter(typeof(TypeTypeConverter))] | |
89 #if !CLIENTPROFILE | |
90 [Editor(typeof(Design.ObjectViewTypeEditor), typeof(UITypeEditor))] | |
91 #endif | |
92 public Type ObjectViewType | |
93 { | |
94 get { return _objectViewType; } | |
95 set | |
96 { | |
97 _objectViewType = value; | |
98 | |
99 List = null; | |
100 | |
101 OnListChanged(ListChangedType.PropertyDescriptorChanged, -1); | |
102 } | |
103 } | |
104 | |
105 private object _object; | |
106 [Browsable(false)] | |
107 [RefreshProperties(RefreshProperties.Repaint)] | |
108 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] | |
109 public object Object | |
110 { | |
111 get { return _object; } | |
112 set | |
113 { | |
114 if (value == null) | |
115 { | |
116 List = null; | |
117 } | |
118 else | |
119 { | |
120 EditableArrayList list = new EditableArrayList(value.GetType(), 1); | |
121 | |
122 list.Add(value, false); | |
123 | |
124 List = list; | |
125 _object = value; | |
126 } | |
127 } | |
128 } | |
129 | |
130 private bool _isListCreatedInternally; | |
131 private EditableArrayList _list = _empty; | |
132 [Browsable(false)] | |
133 [RefreshProperties(RefreshProperties.Repaint)] | |
134 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] | |
135 public IList List | |
136 { | |
137 get { return _list; } | |
138 set | |
139 { | |
140 if (value == null) | |
141 { | |
142 if (_list != _empty) | |
143 _list.ListChanged -= ListChangedHandler; | |
144 | |
145 _list = _itemType == null? _empty: new EditableArrayList(_itemType); | |
146 _isListCreatedInternally = true; | |
147 } | |
148 else | |
149 { | |
150 EditableArrayList list; | |
151 | |
152 if (value is EditableArrayList) | |
153 { | |
154 list = (EditableArrayList)value; | |
155 | |
156 _isListCreatedInternally = false; | |
157 } | |
158 else | |
159 { | |
160 if (value.Count != 0 && _itemType == null) | |
161 list = EditableArrayList.Adapter(value); | |
162 else | |
163 list = EditableArrayList.Adapter(_itemType, value); | |
164 | |
165 _isListCreatedInternally = true; | |
166 } | |
167 | |
168 if (_itemType == null) | |
169 { | |
170 _itemType = list.ItemType; | |
171 } | |
172 else | |
173 { | |
174 if (list.ItemType != _itemType && !list.ItemType.IsSubclassOf(_itemType)) | |
175 throw new ArgumentException(string.Format( | |
176 "Item type {0} of the new list must be a subclass of {1}.", | |
177 list.ItemType, | |
178 _itemType)); | |
179 } | |
180 | |
181 if (_list != _empty) | |
182 { | |
183 _list.ListChanged -= ListChangedHandler; | |
184 | |
185 if (_disposeList || (_isListCreatedInternally && _disposeCreatedList)) | |
186 _list.Dispose(); | |
187 } | |
188 | |
189 _list = list; | |
190 } | |
191 | |
192 if (_list != _empty) | |
193 _list.ListChanged += ListChangedHandler; | |
194 | |
195 OnListChanged(ListChangedType.Reset, -1); | |
196 } | |
197 } | |
198 | |
199 private bool _disposeList; | |
200 [DefaultValue(false)] | |
201 [Category("Behavior")] | |
202 [Description("Determines whether ObjectBinder will invoke underlying List's dispose when being itself disposed.")] | |
203 public bool DisposeList | |
204 { | |
205 get { return _disposeList; } | |
206 set { _disposeList = value; } | |
207 } | |
208 | |
209 private bool _disposeCreatedList = true; | |
210 [DefaultValue(true)] | |
211 [Category("Behavior")] | |
212 [Description("Determines whether ObjectBinder will invoke underlying internally created List's dispose when being itself disposed")] | |
213 public bool DisposeCreatedList | |
214 { | |
215 get { return _disposeCreatedList; } | |
216 set { _disposeCreatedList = value; } | |
217 } | |
218 | |
219 private bool _allowNew = true; | |
220 [DefaultValue(true)] | |
221 [Category("Behavior")] | |
222 [Description("Determines whether new items can be added to the list.")] | |
223 public bool AllowNew | |
224 { | |
225 get { return _allowNew && _list.AllowNew; } | |
226 set { _allowNew = value; } | |
227 } | |
228 | |
229 private bool _allowEdit = true; | |
230 [DefaultValue(true)] | |
231 [Category("Behavior")] | |
232 [Description("Determines whether items in the list can be edited.")] | |
233 public bool AllowEdit | |
234 { | |
235 get { return _allowEdit && _list.AllowEdit; } | |
236 set { _allowEdit = value; } | |
237 } | |
238 | |
239 private bool _allowRemove = true; | |
240 [DefaultValue(true)] | |
241 [Category("Behavior")] | |
242 [Description("Determines whether items can be removed from the list.")] | |
243 public bool AllowRemove | |
244 { | |
245 get { return _allowRemove && _list.AllowRemove; } | |
246 set { _allowRemove = value; } | |
247 } | |
248 | |
249 private IsNullHandler _isNull; | |
250 [Browsable(false)] | |
251 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] | |
252 public IsNullHandler IsNull | |
253 { | |
254 get { return _isNull; } | |
255 set { _isNull = value; } | |
256 } | |
257 | |
258 bool IBindingList.AllowNew { get { return AllowNew; } } | |
259 bool IBindingList.AllowEdit { get { return AllowEdit; } } | |
260 bool IBindingList.AllowRemove { get { return AllowRemove; } } | |
261 | |
262 #endregion | |
263 | |
264 #region Protected Members | |
265 | |
266 protected virtual void OnListChanged(ListChangedEventArgs e) | |
267 { | |
268 ListChangedEventHandler handler = (ListChangedEventHandler)Events[ListChangedEvent]; | |
269 if (handler != null) | |
270 handler(this, e); | |
271 } | |
272 | |
273 protected void OnListChanged(ListChangedType listChangedType, int newIndex) | |
274 { | |
275 OnListChanged(new ListChangedEventArgs(listChangedType, newIndex)); | |
276 } | |
277 | |
278 private void ListChangedHandler(object sender, ListChangedEventArgs e) | |
279 { | |
280 OnListChanged(e); | |
281 } | |
282 | |
283 protected override void Dispose(bool disposing) | |
284 { | |
285 if (_list != _empty) | |
286 { | |
287 _list.ListChanged -= ListChangedHandler; | |
288 | |
289 if (_disposeList || (_isListCreatedInternally && _disposeCreatedList)) | |
290 _list.Dispose(); | |
291 } | |
292 | |
293 _list = _empty; | |
294 | |
295 base.Dispose(disposing); | |
296 } | |
297 | |
298 #endregion | |
299 | |
300 #region ITypedList Members | |
301 | |
302 private static readonly Hashtable _descriptors = new Hashtable(); | |
303 | |
304 PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) | |
305 { | |
306 if (_itemType == null) | |
307 return new PropertyDescriptorCollection(new PropertyDescriptor[0]); | |
308 | |
309 string key = | |
310 _itemType + "." + | |
311 (_objectViewType == null? string.Empty: _objectViewType.ToString()) + "." + | |
312 (_isNull == null? "0": "1"); | |
313 | |
314 if (listAccessors != null) | |
315 foreach (PropertyDescriptor pd in listAccessors) | |
316 key += "." + pd.Name; | |
317 | |
318 PropertyDescriptorCollection pdc = (PropertyDescriptorCollection)_descriptors[key]; | |
319 | |
320 if (pdc == null) | |
321 { | |
322 pdc = _list.GetItemProperties(listAccessors, _objectViewType, _isNull, !DesignMode); | |
323 | |
324 if (!DesignMode) | |
325 _descriptors[key] = pdc; | |
326 } | |
327 | |
328 return pdc; | |
329 } | |
330 | |
331 string ITypedList.GetListName(PropertyDescriptor[] listAccessors) | |
332 { | |
333 return _list.GetListName(listAccessors); | |
334 } | |
335 | |
336 #endregion | |
337 | |
338 #region IBindingListView Members | |
339 | |
340 bool IBindingListView.SupportsAdvancedSorting | |
341 { | |
342 get { return _list.SupportsAdvancedSorting; } | |
343 } | |
344 | |
345 ListSortDescriptionCollection IBindingListView.SortDescriptions | |
346 { | |
347 get { return _list.SortDescriptions; } | |
348 } | |
349 | |
350 void IBindingListView.ApplySort(ListSortDescriptionCollection sorts) | |
351 { | |
352 _list.ApplySort(sorts); | |
353 } | |
354 | |
355 bool IBindingListView.SupportsFiltering | |
356 { | |
357 get { return _list.SupportsFiltering; } | |
358 } | |
359 | |
360 string IBindingListView.Filter | |
361 { | |
362 get { return _list.Filter; } | |
363 set { _list.Filter = value; } | |
364 } | |
365 | |
366 void IBindingListView.RemoveFilter() | |
367 { | |
368 _list.RemoveFilter(); | |
369 } | |
370 | |
371 #endregion | |
372 | |
373 #region ICancelAddNew Members | |
374 | |
375 void ICancelAddNew.CancelNew(int itemIndex) | |
376 { | |
377 _list.CancelNew(itemIndex); | |
378 } | |
379 | |
380 void ICancelAddNew.EndNew(int itemIndex) | |
381 { | |
382 _list.EndNew(itemIndex); | |
383 } | |
384 | |
385 #endregion | |
386 | |
387 #region IBindingList Members | |
388 | |
389 void IBindingList.AddIndex(PropertyDescriptor property) | |
390 { | |
391 _list.AddIndex(property); | |
392 } | |
393 | |
394 object IBindingList.AddNew() | |
395 { | |
396 return _list.AddNew(); | |
397 } | |
398 | |
399 void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction) | |
400 { | |
401 _list.ApplySort(property, direction); | |
402 } | |
403 | |
404 int IBindingList.Find(PropertyDescriptor property, object key) | |
405 { | |
406 return _list.Find(property, key); | |
407 } | |
408 | |
409 bool IBindingList.IsSorted | |
410 { | |
411 get { return _list.IsSorted; } | |
412 } | |
413 | |
414 private static readonly object ListChangedEvent = new object(); | |
415 | |
416 public event ListChangedEventHandler ListChanged | |
417 { | |
418 add { Events.AddHandler (ListChangedEvent, value); } | |
419 remove { Events.RemoveHandler(ListChangedEvent, value); } | |
420 } | |
421 | |
422 void IBindingList.RemoveIndex(PropertyDescriptor property) | |
423 { | |
424 _list.RemoveIndex(property); | |
425 } | |
426 | |
427 void IBindingList.RemoveSort() | |
428 { | |
429 _list.RemoveSort(); | |
430 } | |
431 | |
432 ListSortDirection IBindingList.SortDirection | |
433 { | |
434 get { return _list.SortDirection; } | |
435 } | |
436 | |
437 PropertyDescriptor IBindingList.SortProperty | |
438 { | |
439 get { return _list.SortProperty; } | |
440 } | |
441 | |
442 bool IBindingList.SupportsChangeNotification | |
443 { | |
444 get { return _list.SupportsChangeNotification; } | |
445 } | |
446 | |
447 bool IBindingList.SupportsSearching | |
448 { | |
449 get { return _list.SupportsSearching; } | |
450 } | |
451 | |
452 bool IBindingList.SupportsSorting | |
453 { | |
454 get { return _list.SupportsSorting; } | |
455 } | |
456 | |
457 #endregion | |
458 | |
459 #region IList Members | |
460 | |
461 int IList.Add(object value) | |
462 { | |
463 return _list.Add(value); | |
464 } | |
465 | |
466 void IList.Clear() | |
467 { | |
468 _list.Clear(); | |
469 } | |
470 | |
471 bool IList.Contains(object value) | |
472 { | |
473 return _list.Contains(value); | |
474 } | |
475 | |
476 int IList.IndexOf(object value) | |
477 { | |
478 return _list.IndexOf(value); | |
479 } | |
480 | |
481 void IList.Insert(int index, object value) | |
482 { | |
483 _list.Insert(index, value); | |
484 } | |
485 | |
486 bool IList.IsFixedSize | |
487 { | |
488 get { return _list.IsFixedSize; } | |
489 } | |
490 | |
491 bool IList.IsReadOnly | |
492 { | |
493 get { return _list.IsReadOnly; } | |
494 } | |
495 | |
496 void IList.Remove(object value) | |
497 { | |
498 _list.Remove(value); | |
499 } | |
500 | |
501 void IList.RemoveAt(int index) | |
502 { | |
503 _list.RemoveAt(index); | |
504 } | |
505 | |
506 object IList.this[int index] | |
507 { | |
508 get { return index == -1? null: _list[index]; } | |
509 set { _list[index] = value; } | |
510 } | |
511 | |
512 #endregion | |
513 | |
514 #region ICollection Members | |
515 | |
516 void ICollection.CopyTo(Array array, int index) | |
517 { | |
518 _list.CopyTo(array, index); | |
519 } | |
520 | |
521 int ICollection.Count | |
522 { | |
523 get { return _list.Count; } | |
524 } | |
525 | |
526 bool ICollection.IsSynchronized | |
527 { | |
528 get { return _list.IsSynchronized; } | |
529 } | |
530 | |
531 object ICollection.SyncRoot | |
532 { | |
533 get { return _list.SyncRoot; } | |
534 } | |
535 | |
536 #endregion | |
537 | |
538 #region IEnumerable Members | |
539 | |
540 IEnumerator IEnumerable.GetEnumerator() | |
541 { | |
542 return _list.GetEnumerator(); | |
543 } | |
544 | |
545 #endregion | |
546 } | |
547 } |