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 } |
