1 //------------------------------------------------------------------------------ 2 // <copyright file="ObjectList.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 using System; 8 using System.Collections; 9 using System.ComponentModel; 10 using System.Data; 11 using System.Diagnostics; 12 using System.Drawing.Design; 13 using System.Globalization; 14 using System.Web; 15 using System.Web.UI; 16 using System.Web.UI.WebControls; 17 using System.Web.UI.HtmlControls; 18 using System.Security.Permissions; 19 20 namespace System.Web.UI.MobileControls 21 { 22 /* 23 * Object List class. 24 * 25 * Copyright (c) 2000 Microsoft Corporation 26 */ 27 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList"]/*' /> 28 [ 29 ControlBuilderAttribute(typeof(ObjectListControlBuilder)), 30 DefaultEvent("ItemCommand"), 31 DefaultProperty("DataSource"), 32 Designer(typeof(System.Web.UI.Design.MobileControls.ObjectListDesigner)), 33 DesignerAdapter(typeof(System.Web.UI.Design.MobileControls.Adapters.DesignerObjectListAdapter)), 34 Editor(typeof(System.Web.UI.Design.MobileControls.ObjectListComponentEditor), typeof(ComponentEditor)), 35 ToolboxData("<{0}:ObjectList runat=\"server\" LabelStyle-StyleReference=\"title\" CommandStyle-StyleReference=\"subcommand\"></{0}:ObjectList>"), 36 ToolboxItem("System.Web.UI.Design.WebControlToolboxItem, " + AssemblyRef.SystemDesign) 37 ] 38 [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 39 [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 40 [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] 41 public class ObjectList : PagedControl, INamingContainer, ITemplateable, IPostBackEventHandler 42 { 43 private static readonly Object EventItemDataBind = new Object(); 44 private static readonly Object EventItemCommand = new Object(); 45 private static readonly Object EventItemSelect = new Object(); 46 private static readonly Object EventShowItemCommands = new Object(); 47 48 private Object _dataSource; 49 private IEnumerable _resolvedDataSource; 50 private ObjectListFieldCollection _fields; 51 private ObjectListFieldCollection _autoGeneratedFields; 52 private ObjectListFieldCollection _allFields; 53 private ObjectListItemCollection _items; 54 private ObjectListCommandCollection _commands; 55 private ObjectListCommandCollection _globalCommands; 56 private int _labelFieldIndex = -1; 57 private int[] _tableFieldIndices = null; 58 private IEnumerator _storedEnumerator = null; 59 private Object _firstDataItem = null; 60 private bool _storedDataValid = false; 61 private ObjectListViewMode _viewMode = ObjectListViewMode.List; 62 private bool _ignoreFieldsItemsViewModeViewState = false; 63 private Style _commandStyle = null; 64 private Style _labelStyle = null; 65 private const string _itemCountViewStateKey = "_!ItemCount"; 66 private int _selectedIndex = -1; 67 private bool _selectedIndexDirty = false; 68 private bool _loadingItems = false; 69 70 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SelectMoreCommand"]/*' /> 71 public static String SelectMoreCommand 72 { 73 get 74 { 75 return "More"; 76 } 77 } 78 79 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DataSource"]/*' /> 80 [ 81 Bindable(true), 82 DefaultValue(null), 83 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 84 MobileCategory(SR.Category_Data), 85 MobileSysDescription(SR.ObjectList_DataSource) 86 ] 87 public virtual Object DataSource 88 { 89 get 90 { 91 return _dataSource; 92 } 93 set 94 { 95 _dataSource = value; 96 // _allFields and _resolvedDataSource need to be recalculated. 97 _allFields = null; 98 _resolvedDataSource = null; 99 } 100 } 101 102 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DataMember"]/*' /> 103 [ 104 Bindable(false), 105 DefaultValue(""), 106 MobileCategory(SR.Category_Data), 107 MobileSysDescription(SR.List_DataMember), 108 TypeConverter(typeof(System.Web.UI.Design.MobileControls.Converters.DataMemberConverter)) 109 ] 110 public virtual String DataMember 111 { 112 get 113 { 114 String s = (String)ViewState["DataMember"]; 115 return s == null ? String.Empty : s; 116 } 117 set 118 { 119 ViewState["DataMember"] = value; 120 } 121 } 122 123 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Fields"]/*' /> 124 [ 125 Bindable(false), 126 DefaultValue(null), 127 Editor(typeof(System.Web.UI.Design.MobileControls.FieldCollectionEditor), typeof(UITypeEditor)), 128 MergableProperty(false), 129 MobileCategory(SR.Category_Data), 130 MobileSysDescription(SR.ObjectList_Fields), 131 PersistenceMode(PersistenceMode.InnerDefaultProperty) 132 ] 133 public virtual ObjectListFieldCollection Fields 134 { 135 get 136 { 137 if (_fields == null) 138 { 139 _fields = new ObjectListFieldCollection(this); 140 if (IsTrackingViewState) 141 { 142 ((IStateManager)_fields).TrackViewState(); 143 } 144 } 145 return _fields; 146 } 147 } 148 149 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Items"]/*' /> 150 [ 151 Bindable(true), 152 Browsable(false), 153 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 154 ] 155 public virtual ObjectListItemCollection Items 156 { 157 get 158 { 159 if (_items == null) 160 { 161 _items = new ObjectListItemCollection(this); 162 if (IsTrackingViewState) 163 { 164 ((IStateManager)_items).TrackViewState(); 165 } 166 } 167 return _items; 168 } 169 } 170 171 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Commands"]/*' /> 172 [ 173 Bindable(false), 174 Editor(typeof(System.Web.UI.Design.MobileControls.CommandCollectionEditor), typeof(UITypeEditor)), 175 MergableProperty(false), 176 MobileCategory(SR.Category_Data), 177 MobileSysDescription(SR.ObjectList_Commands), 178 PersistenceMode(PersistenceMode.InnerDefaultProperty) 179 ] 180 public virtual ObjectListCommandCollection Commands 181 { 182 get 183 { 184 if (_commands == null) 185 { 186 _commands = new ObjectListCommandCollection(); 187 if (IsTrackingViewState) 188 { 189 ((IStateManager)_commands).TrackViewState(); 190 } 191 } 192 return _commands; 193 } 194 } 195 196 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LabelField"]/*' /> 197 [ 198 DefaultValue(""), 199 MobileCategory(SR.Category_Data), 200 MobileSysDescription(SR.ObjectList_LabelField), 201 TypeConverter(typeof(System.Web.UI.Design.MobileControls.Converters.DataFieldConverter)) 202 ] 203 public String LabelField 204 { 205 get 206 { 207 String s = (String)ViewState["LabelField"]; 208 return (s != null) ? s : String.Empty; 209 } 210 set 211 { 212 ViewState["LabelField"] = value; 213 InvalidateDisplayFieldIndices(); 214 } 215 } 216 217 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DefaultCommand"]/*' /> 218 [ 219 Bindable(true), 220 DefaultValue(""), 221 MobileCategory(SR.Category_Data), 222 MobileSysDescription(SR.ObjectList_DefaultCommand), 223 TypeConverter(typeof(System.Web.UI.Design.MobileControls.Converters.DefaultCommandConverter)) 224 ] 225 public String DefaultCommand 226 { 227 get 228 { 229 String s = (String)ViewState["DefaultCommand"]; 230 return (s != null) ? s : String.Empty; 231 } 232 set 233 { 234 ViewState["DefaultCommand"] = value; 235 } 236 } 237 238 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.TableFields"]/*' /> 239 [ 240 Bindable(true), 241 DefaultValue(""), 242 Editor(typeof(System.Web.UI.Design.MobileControls.TableFieldsEditor), 243 typeof(UITypeEditor)), 244 MobileCategory(SR.Category_Data), 245 MobileSysDescription(SR.ObjectList_TableFields) 246 ] 247 public String TableFields 248 { 249 get 250 { 251 String s = (String)ViewState["TableFields"]; 252 return (s != null) ? s : String.Empty; 253 } 254 set 255 { 256 ViewState["TableFields"] = value; 257 InvalidateDisplayFieldIndices(); 258 } 259 } 260 261 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SelectedIndex"]/*' /> 262 [ 263 Bindable(false), 264 Browsable(false), 265 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 266 ] 267 public int SelectedIndex 268 { 269 get 270 { 271 return _selectedIndex; 272 } 273 set 274 { 275 if (value == -1 && ViewMode != ObjectListViewMode.List) 276 { 277 throw new Exception( 278 SR.GetString(SR.ObjectList_MustBeInListModeToClearSelectedIndex)); 279 } 280 int itemCount = ItemCount > 0 ? ItemCount : Items.Count; 281 if (value < -1) 282 { 283 throw new ArgumentOutOfRangeException("SelectedIndex", 284 SR.GetString(SR.ObjectList_SelectedIndexTooSmall, value)); 285 } 286 else if (itemCount > 0 && value >= itemCount) 287 { 288 throw new ArgumentOutOfRangeException("SelectedIndex", 289 SR.GetString(SR.ObjectList_SelectedIndexTooBig, value, itemCount)); 290 } 291 // End of guard clauses. 292 293 _selectedIndexDirty = (value != _selectedIndex) && IsTrackingViewState; 294 DeselectItemIfLoaded(_selectedIndex); 295 SelectItemIfLoaded(value); 296 _selectedIndex = value; 297 } 298 } 299 300 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Selection"]/*' /> 301 [ 302 Bindable(false), 303 Browsable(false), 304 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 305 ] 306 public ObjectListItem Selection 307 { 308 get 309 { 310 if (SelectedIndex == -1) 311 { 312 return null; 313 } 314 EnsureItemLoaded (SelectedIndex); 315 int selectedIndex = TranslateVirtualItemIndex(SelectedIndex); 316 if (selectedIndex >= 0 && selectedIndex < Items.Count) 317 { 318 Debug.Assert (Items[selectedIndex].Selected); 319 return Items[selectedIndex]; 320 } 321 else 322 { 323 return null; 324 } 325 } 326 } 327 328 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.AutoGenerateFields"]/*' /> 329 [ 330 Bindable(false), 331 Browsable(true), 332 DefaultValue(true), 333 MobileCategory(SR.Category_Behavior), 334 MobileSysDescription(SR.ObjectList_AutoGenerateFields) 335 ] 336 public bool AutoGenerateFields 337 { 338 get 339 { 340 Object b = ViewState["AutoGenerateFields"]; 341 return (b != null) ? (bool)b : true; 342 } 343 set 344 { 345 if (value != AutoGenerateFields) 346 { 347 ViewState["AutoGenerateFields"] = value; 348 _allFields = null; 349 _autoGeneratedFields = null; 350 _items = null; 351 InvalidateDisplayFieldIndices(); 352 } 353 } 354 } 355 356 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.AllFields"]/*' /> 357 [ 358 Bindable(false), 359 Browsable(false), 360 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 361 ] 362 public IObjectListFieldCollection AllFields 363 { 364 get 365 { 366 if (_allFields == null) 367 { 368 if (_autoGeneratedFields == null) 369 { 370 if (_fields == null) 371 { 372 return null; 373 } 374 else 375 { 376 _allFields = _fields; 377 } 378 } 379 else 380 { 381 if (_fields == null) 382 { 383 _allFields = _autoGeneratedFields; 384 } 385 else 386 { 387 int count = _fields.Count + _autoGeneratedFields.Count; 388 389 ArrayList list = new ArrayList(count); 390 391 foreach (ObjectListField field in _fields) 392 { 393 list.Add(field); 394 } 395 396 foreach (ObjectListField field in _autoGeneratedFields) 397 { 398 list.Add(field); 399 } 400 401 _allFields = new ObjectListFieldCollection(this, list); 402 } 403 } 404 } 405 return _allFields; 406 } 407 } 408 409 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LabelFieldIndex"]/*' /> 410 [ 411 Bindable(false), 412 Browsable(false), 413 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 414 ] 415 public int LabelFieldIndex 416 { 417 get 418 { 419 if (_labelFieldIndex == -1) 420 { 421 CalculateDisplayFieldIndices(); 422 } 423 return _labelFieldIndex; 424 } 425 } 426 427 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Details"]/*' /> 428 [ 429 Bindable(false), 430 Browsable(false), 431 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 432 ] 433 public Panel Details 434 { 435 get 436 { 437 EnsureChildControls(); 438 if (ViewMode != ObjectListViewMode.Details) 439 { 440 throw new Exception(SR.GetString(SR.ObjectList_MustBeInDetailsModeToGetDetails)); 441 } 442 return Selection; 443 } 444 } 445 446 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.TableFieldIndices"]/*' /> 447 [ 448 Bindable(false), 449 Browsable(false), 450 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 451 ] 452 public int[] TableFieldIndices 453 { 454 get 455 { 456 if (_labelFieldIndex == -1) 457 { 458 CalculateDisplayFieldIndices(); 459 } 460 Debug.Assert(_tableFieldIndices != null, "_tableFieldIndices is null."); 461 return _tableFieldIndices; 462 } 463 } 464 465 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.EnsureTemplatedUI"]/*' /> EnsureTemplatedUI()466 public override void EnsureTemplatedUI() 467 { 468 EnsureChildControls(); 469 } 470 471 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.EnsureChildControls"]/*' /> EnsureChildControls()472 protected override void EnsureChildControls() 473 { 474 // if EnsureChildControls is called before items are created (e.g., at 475 // LoadPrivateViewState), there will be no controls. Need to build child 476 // controls in this case, so we set ChildControlsCreated to false. 477 ChildControlsCreated = ChildControlsCreated && Controls.Count > 0; 478 base.EnsureChildControls(); 479 } 480 CalculateDisplayFieldIndices()481 private void CalculateDisplayFieldIndices() 482 { 483 String labelField = LabelField; 484 if (labelField.Length > 0) 485 { 486 _labelFieldIndex = GetFieldIndex(labelField); 487 } 488 else 489 { 490 _labelFieldIndex = 0; 491 } 492 493 String tableFields = TableFields; 494 int length = tableFields.Length; 495 496 // Populate the _tableFieldIndices array. 497 ArrayList tableFieldIndexList = new ArrayList(); 498 for (int pos = 0; pos < length; ) 499 { 500 int nextSemicolon = tableFields.IndexOf(';', pos); 501 String fieldName = (nextSemicolon == -1) ? 502 tableFields.Substring(pos) : 503 tableFields.Substring(pos, nextSemicolon - pos); 504 tableFieldIndexList.Add(GetFieldIndex(fieldName)); 505 pos = nextSemicolon == -1 ? length : nextSemicolon + 1; 506 } 507 _tableFieldIndices = (int[])tableFieldIndexList.ToArray(typeof(int)); 508 } 509 InvalidateDisplayFieldIndices()510 internal void InvalidateDisplayFieldIndices() 511 { 512 _labelFieldIndex = -1; 513 _tableFieldIndices = null; 514 } 515 GetFieldIndex(String field)516 private int GetFieldIndex(String field) 517 { 518 int index = AllFields.IndexOf(field); 519 if (index == -1) 520 { 521 throw new ArgumentException(SR.GetString( 522 SR.ObjectList_FieldNotFound, field)); 523 } 524 return index; 525 } 526 527 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.AddParsedSubObject"]/*' /> AddParsedSubObject(Object obj)528 protected override void AddParsedSubObject(Object obj) 529 { 530 if (!(obj is LiteralControl)) 531 { 532 if (obj is ObjectListField) 533 { 534 Fields.Add((ObjectListField)obj); 535 } 536 else if (obj is ObjectListCommand) 537 { 538 Commands.Add((ObjectListCommand)obj); 539 } 540 else 541 { 542 base.AddParsedSubObject(obj); 543 } 544 } 545 } 546 547 private IEnumerable ResolvedDataSource 548 { 549 get 550 { 551 if (_resolvedDataSource == null) 552 { 553 _resolvedDataSource = 554 DataSourceHelper.GetResolvedDataSource(DataSource, DataMember); 555 } 556 return _resolvedDataSource; 557 } 558 } 559 560 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateChildControls"]/*' /> CreateChildControls()561 protected override void CreateChildControls() 562 { 563 Controls.Clear(); 564 if (ViewState[_itemCountViewStateKey] != null) 565 { 566 CreateChildControls(false); 567 } 568 } 569 CreateChildControls(bool doDataBind)570 private void CreateChildControls(bool doDataBind) 571 { 572 if (IsTemplated) 573 { 574 Controls.Clear(); 575 CreateTemplatedUI(doDataBind); 576 ChildControlsCreated = true; 577 } 578 } 579 580 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DataBind"]/*' /> DataBind()581 public override void DataBind() 582 { 583 // Do our own databinding 584 OnDataBinding(EventArgs.Empty); 585 586 // Contained items will be databound after they have been created, 587 // so we don't want to walk the hierarchy here. 588 } 589 590 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnDataBinding"]/*' /> OnDataBinding(EventArgs e)591 protected override void OnDataBinding(EventArgs e) 592 { 593 base.OnDataBinding(e); 594 595 if (ResolvedDataSource == null) 596 { 597 ClearItemsAndControls(); 598 return; 599 } 600 601 if (AutoGenerateFields) 602 { 603 CreateAutoGeneratedFields(ResolvedDataSource); 604 } 605 606 if ((AllFields == null || AllFields.Count == 0) 607 && MobilePage != null 608 && !MobilePage.DesignMode) 609 { 610 throw new Exception( 611 SR.GetString(SR.ObjectList_MustHaveOneOrMoreFields)); 612 } 613 614 CreateItems(ResolvedDataSource); 615 616 if (!_loadingItems) 617 { 618 // To clear the selected index, the ViewMode must be list. 619 ViewMode = ObjectListViewMode.List; 620 SelectedIndex = -1; 621 } 622 else 623 { 624 SelectItemIfLoaded(SelectedIndex); 625 } 626 627 CreateChildControls(true); 628 } 629 630 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateTemplatedItemsList"]/*' /> CreateTemplatedItemsList(bool doDataBind)631 public void CreateTemplatedItemsList(bool doDataBind) 632 { 633 ObjectListItemCollection items = Items; 634 635 ITemplate headerTemplate = GetTemplate(Constants.HeaderTemplateTag); 636 ITemplate footerTemplate = GetTemplate(Constants.FooterTemplateTag); 637 ITemplate itemTemplate = GetTemplate(Constants.ItemTemplateTag); 638 ITemplate separatorTemplate = GetTemplate(Constants.SeparatorTemplateTag); 639 ITemplate alternatingItemTemplate = GetTemplate(Constants.AlternatingItemTemplateTag); 640 if (alternatingItemTemplate == null) 641 { 642 alternatingItemTemplate = itemTemplate; 643 } 644 645 CreateControlItem(MobileListItemType.HeaderItem, headerTemplate, doDataBind); 646 for (int i = 0; i < items.Count; i++) 647 { 648 if (i > 0) 649 { 650 CreateControlItem(MobileListItemType.SeparatorItem, 651 separatorTemplate, 652 doDataBind); 653 } 654 AddItemAsControl(i, items[i], 655 ((i & 1) == 1) ? alternatingItemTemplate : itemTemplate, 656 doDataBind); 657 } 658 CreateControlItem(MobileListItemType.FooterItem, footerTemplate, doDataBind); 659 } 660 AddItemAsControl( int itemIndex, MobileListItem item, ITemplate itemTemplate, bool doDataBind)661 private void AddItemAsControl( 662 int itemIndex, 663 MobileListItem item, 664 ITemplate itemTemplate, 665 bool doDataBind) 666 { 667 if (itemTemplate != null) 668 { 669 // No need to do it again, since CreateItems already does it. 670 item.Controls.Clear(); 671 item.ID = null; 672 Controls.Add(item); 673 CheckedInstantiateTemplate (itemTemplate, item, this); 674 if (doDataBind) 675 { 676 item.DataBind(); 677 } 678 } 679 } 680 CreateControlItem( MobileListItemType itemType, ITemplate itemTemplate, bool doDataBind)681 private void CreateControlItem( 682 MobileListItemType itemType, 683 ITemplate itemTemplate, 684 bool doDataBind) 685 { 686 if (itemTemplate != null) 687 { 688 MobileListItem item = new MobileListItem(itemType); 689 AddItemAsControl(-1, item, itemTemplate, doDataBind); 690 } 691 } 692 693 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateTemplatedItemDetails"]/*' /> CreateTemplatedItemDetails(bool doDataBind)694 public void CreateTemplatedItemDetails(bool doDataBind) 695 { 696 ITemplate detailsTemplate = GetTemplate(Constants.ItemDetailsTemplateTag); 697 Selection.Controls.Clear(); 698 699 // Selection ID must be the same on each request. AUI 8007. 700 Selection.ID = "_ctl"; 701 702 if (detailsTemplate != null) 703 { 704 if (!Controls.Contains (Selection)) 705 { 706 Controls.Add (Selection); 707 } 708 CheckedInstantiateTemplate (detailsTemplate, Selection, this); 709 if (doDataBind) 710 { 711 Selection.DataBind(); 712 } 713 } 714 } 715 716 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateItems"]/*' /> CreateItems(IEnumerable dataSource)717 protected virtual void CreateItems(IEnumerable dataSource) 718 { 719 Debug.Assert (dataSource != null, "dataSource is null"); 720 721 Items.Clear(); 722 723 int count = 0; 724 IEnumerator enumerator; 725 726 if(_storedDataValid && _firstDataItem != null) 727 { 728 enumerator = _storedEnumerator; 729 ObjectListItem item = CreateItem(_firstDataItem); 730 item.SetIndex(count + Items.BaseIndex); 731 Items.Add(item); 732 count++; 733 _storedDataValid = false; 734 _firstDataItem = null; 735 _storedEnumerator = null; 736 } 737 else 738 { 739 enumerator = dataSource.GetEnumerator(); 740 } 741 742 while(enumerator.MoveNext()) 743 { 744 Object dataItem = enumerator.Current; 745 ObjectListItem item = CreateItem(dataItem); 746 item.SetIndex(count + Items.BaseIndex); 747 Items.Add(item); 748 count++; 749 } 750 } 751 752 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateItem"]/*' /> CreateItem(Object dataItem)753 protected virtual ObjectListItem CreateItem(Object dataItem) 754 { 755 ObjectListItem item = new ObjectListItem(this, dataItem); 756 757 // Set fields. 758 759 IObjectListFieldCollection allFields = AllFields; 760 int fieldIndex = 0; 761 foreach (ObjectListField field in AllFields) 762 { 763 field.DataBindItem(fieldIndex, item); 764 fieldIndex++; 765 } 766 767 // Use delegated data binding, if specified. 768 769 if (dataItem != null) 770 { 771 OnItemDataBind(new ObjectListDataBindEventArgs(item, dataItem)); 772 } 773 774 return item; 775 } 776 777 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnPreRender"]/*' /> OnPreRender(EventArgs e)778 protected override void OnPreRender(EventArgs e) 779 { 780 base.OnPreRender(e); 781 782 if (IsTemplated) 783 { 784 int firstVisibleItem = FirstVisibleItemIndex; 785 int pageSize = VisibleItemCount; 786 int lastVisibleItem = firstVisibleItem + pageSize - 1; 787 int itemIndex = 0; 788 int separatorIndex = 0; 789 foreach(Control ctl in Controls) 790 { 791 MobileListItem item = ctl as MobileListItem; 792 if (item != null) 793 { 794 if (item.ItemType == MobileListItemType.ListItem) 795 { 796 item.Visible = itemIndex >= firstVisibleItem && itemIndex <= lastVisibleItem; 797 itemIndex++; 798 } 799 else if (item.ItemType == MobileListItemType.SeparatorItem) 800 { 801 item.Visible = separatorIndex >= firstVisibleItem && 802 separatorIndex < lastVisibleItem; 803 separatorIndex++; 804 } 805 } 806 } 807 } 808 } 809 810 ///////////////////////////////////////////////////////////////////////// 811 // FIELD AUTO-GENERATION 812 ///////////////////////////////////////////////////////////////////////// 813 814 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateAutoGeneratedFields"]/*' /> CreateAutoGeneratedFields(IEnumerable dataSource)815 protected void CreateAutoGeneratedFields(IEnumerable dataSource) 816 { 817 if (dataSource == null) 818 { 819 return; 820 } 821 822 ArrayList list = new ArrayList(); 823 PropertyDescriptorCollection propertyDescriptors = null; 824 825 if (dataSource is ITypedList) 826 { 827 propertyDescriptors = 828 ((ITypedList)dataSource).GetItemProperties(new PropertyDescriptor[0]); 829 } 830 831 if (propertyDescriptors == null) 832 { 833 IEnumerator enumerator = dataSource.GetEnumerator(); 834 if (enumerator.MoveNext()) 835 { 836 Object sampleItem = enumerator.Current; 837 StoreEnumerator(enumerator, sampleItem); 838 if (IsBindableType(sampleItem.GetType())) 839 { 840 list.Add(CreateAutoGeneratedField( 841 SR.GetString(SR.ObjectList_ItemTitle), 842 null)); 843 } 844 else 845 { 846 propertyDescriptors = TypeDescriptor.GetProperties(sampleItem); 847 } 848 } 849 } 850 851 if (propertyDescriptors != null && propertyDescriptors.Count > 0) 852 { 853 foreach (PropertyDescriptor pd in propertyDescriptors) 854 { 855 if (IsBindableType(pd.PropertyType)) 856 { 857 String title; 858 ObjectListTitleAttribute attr = 859 (ObjectListTitleAttribute)pd.Attributes[typeof(ObjectListTitleAttribute)]; 860 if (attr != null) 861 { 862 title = attr.Title; 863 } 864 else 865 { 866 title = pd.Name; 867 } 868 list.Add(CreateAutoGeneratedField(title, pd.Name)); 869 } 870 } 871 } 872 873 _autoGeneratedFields = new ObjectListFieldCollection(this, list); 874 } 875 876 /// Caches the fact that we have already consumed the first item from the enumeration 877 /// and must use it first during our item creation. StoreEnumerator(IEnumerator enumerator, object firstDataItem)878 internal void StoreEnumerator(IEnumerator enumerator, object firstDataItem) 879 { 880 _storedEnumerator = enumerator; 881 _firstDataItem = firstDataItem; 882 _storedDataValid = true; 883 } 884 IsBindableType(Type type)885 private bool IsBindableType(Type type) 886 { 887 return(type.IsPrimitive || 888 (type == typeof(String)) || 889 (type == typeof(DateTime)) || 890 (type == typeof(Decimal))); 891 } 892 CreateAutoGeneratedField(String title, String dataField)893 private ObjectListField CreateAutoGeneratedField(String title, String dataField) 894 { 895 ObjectListField field = new ObjectListField(); 896 ((IStateManager)field).TrackViewState(); 897 field.Title = title; 898 if (dataField != null) 899 { 900 field.DataField = dataField; 901 } 902 else 903 { 904 field.SelfReference = true; 905 } 906 return field; 907 } 908 SaveAutoFieldsState()909 Object SaveAutoFieldsState() 910 { 911 int autoGeneratedCount = (_autoGeneratedFields != null) ? _autoGeneratedFields.Count : 0; 912 if (autoGeneratedCount != 0) 913 { 914 Object[] fieldStates = new Object[autoGeneratedCount]; 915 for (int i = 0; i < autoGeneratedCount; i++) 916 { 917 fieldStates[i] = ((IStateManager)_autoGeneratedFields[i]).SaveViewState(); 918 } 919 return fieldStates; 920 } 921 else 922 { 923 return null; 924 } 925 } 926 LoadAutoFieldsState(Object state)927 void LoadAutoFieldsState(Object state) 928 { 929 if (state != null) 930 { 931 Object[] fieldStates = (Object[])state; 932 int count = fieldStates.Length; 933 ArrayList list = new ArrayList(count); 934 foreach (Object fieldState in fieldStates) 935 { 936 ObjectListField field = new ObjectListField(); 937 ((IStateManager)field).TrackViewState(); 938 ((IStateManager)field).LoadViewState (fieldState); 939 list.Add(field); 940 } 941 _autoGeneratedFields = new ObjectListFieldCollection(this, list); 942 } 943 } 944 OnFieldChanged(bool fieldAddedOrRemoved)945 internal void OnFieldChanged(bool fieldAddedOrRemoved) 946 { 947 // Called when a field is added, removed, etc. 948 if (IsTrackingViewState) 949 { 950 _items = null; 951 // avoid view state being out of sync with fields. 952 _ignoreFieldsItemsViewModeViewState = true; 953 if (fieldAddedOrRemoved) 954 { 955 _allFields = null; 956 } 957 InvalidateDisplayFieldIndices(); 958 } 959 } 960 961 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.InternalItemCount"]/*' /> 962 protected override int InternalItemCount 963 { 964 get 965 { 966 if (_items != null && Items.Count > 0) 967 { 968 return Items.Count; 969 } 970 else 971 { 972 return 0; 973 } 974 } 975 976 } 977 978 ///////////////////////////////////////////////////////////////////////// 979 // EVENT HANDLING 980 ///////////////////////////////////////////////////////////////////////// 981 982 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ItemDataBind"]/*' /> 983 [ 984 MobileCategory(SR.Category_Action), 985 MobileSysDescription(SR.ObjectList_OnItemDataBind) 986 ] 987 public event ObjectListDataBindEventHandler ItemDataBind 988 { 989 add 990 { 991 Events.AddHandler(EventItemDataBind, value); 992 } 993 remove 994 { 995 Events.RemoveHandler(EventItemDataBind, value); 996 } 997 } 998 999 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnItemDataBind"]/*' /> OnItemDataBind(ObjectListDataBindEventArgs e)1000 protected virtual void OnItemDataBind(ObjectListDataBindEventArgs e) 1001 { 1002 ObjectListDataBindEventHandler onItemDataBindHandler = 1003 (ObjectListDataBindEventHandler)Events[EventItemDataBind]; 1004 if (onItemDataBindHandler != null) 1005 { 1006 onItemDataBindHandler(this, e); 1007 } 1008 } 1009 1010 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ItemCommand"]/*' /> 1011 [ 1012 MobileCategory(SR.Category_Action), 1013 MobileSysDescription(SR.ObjectList_OnItemCommand) 1014 ] 1015 public event ObjectListCommandEventHandler ItemCommand 1016 { 1017 add 1018 { 1019 Events.AddHandler(EventItemCommand, value); 1020 } 1021 remove 1022 { 1023 Events.RemoveHandler(EventItemCommand, value); 1024 } 1025 } 1026 1027 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnItemCommand"]/*' /> OnItemCommand(ObjectListCommandEventArgs e)1028 protected virtual void OnItemCommand(ObjectListCommandEventArgs e) 1029 { 1030 ObjectListCommandEventHandler onItemCommandHandler = (ObjectListCommandEventHandler)Events[EventItemCommand]; 1031 if (onItemCommandHandler != null) 1032 { 1033 onItemCommandHandler(this, e); 1034 } 1035 } 1036 1037 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ItemSelect"]/*' /> 1038 [ 1039 MobileCategory(SR.Category_Action), 1040 MobileSysDescription(SR.ObjectList_OnItemSelect) 1041 ] 1042 public event ObjectListSelectEventHandler ItemSelect 1043 { 1044 add 1045 { 1046 Events.AddHandler(EventItemSelect, value); 1047 } 1048 remove 1049 { 1050 Events.RemoveHandler(EventItemSelect, value); 1051 } 1052 } 1053 1054 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnItemSelect"]/*' /> OnItemSelect(ObjectListSelectEventArgs e)1055 protected virtual void OnItemSelect(ObjectListSelectEventArgs e) 1056 { 1057 ObjectListSelectEventHandler onItemSelectHandler = (ObjectListSelectEventHandler)Events[EventItemSelect]; 1058 if (onItemSelectHandler != null) 1059 { 1060 onItemSelectHandler(this, e); 1061 } 1062 } 1063 1064 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.HasItemCommandHandler"]/*' /> 1065 [ 1066 Bindable(false), 1067 Browsable(false), 1068 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 1069 ] 1070 public bool HasItemCommandHandler 1071 { 1072 get 1073 { 1074 return Events[EventItemCommand] != null; 1075 } 1076 } 1077 1078 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ShowItemCommands"]/*' /> 1079 [ 1080 MobileCategory(SR.Category_Action), 1081 MobileSysDescription(SR.ObjectList_OnShowItemCommands) 1082 ] 1083 public event ObjectListShowCommandsEventHandler ShowItemCommands 1084 { 1085 add 1086 { 1087 Events.AddHandler(EventShowItemCommands, value); 1088 } 1089 remove 1090 { 1091 Events.RemoveHandler(EventShowItemCommands, value); 1092 } 1093 } 1094 1095 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnShowItemCommands"]/*' /> OnShowItemCommands(ObjectListShowCommandsEventArgs e)1096 protected virtual void OnShowItemCommands(ObjectListShowCommandsEventArgs e) 1097 { 1098 ObjectListShowCommandsEventHandler onShowItemCommandsHandler 1099 = (ObjectListShowCommandsEventHandler)Events[EventShowItemCommands]; 1100 if (onShowItemCommandsHandler != null) 1101 { 1102 onShowItemCommandsHandler(this, e); 1103 } 1104 } 1105 1106 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnBubbleEvent"]/*' /> OnBubbleEvent(Object sender, EventArgs e)1107 protected override bool OnBubbleEvent(Object sender, EventArgs e) 1108 { 1109 bool handled = false; 1110 1111 if (e is CommandEventArgs) 1112 { 1113 if (e is ObjectListCommandEventArgs) 1114 { 1115 OnItemCommand((ObjectListCommandEventArgs)e); 1116 handled = true; 1117 } 1118 } 1119 1120 return handled; 1121 } 1122 1123 /// <internalonly/> RaisePostBackEvent(String eventArgument)1124 protected void RaisePostBackEvent(String eventArgument) 1125 { 1126 if (!Adapter.HandlePostBackEvent(eventArgument)) 1127 { 1128 OnItemCommand(new ObjectListCommandEventArgs(Selection, eventArgument)); 1129 } 1130 } 1131 1132 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.RaiseDefaultItemEvent"]/*' /> RaiseDefaultItemEvent(int itemIndex)1133 public void RaiseDefaultItemEvent(int itemIndex) 1134 { 1135 EnsureItemLoaded (itemIndex); 1136 int itemCollIndex = TranslateVirtualItemIndex(itemIndex); 1137 SelectedIndex = itemIndex; 1138 OnItemCommand(new ObjectListCommandEventArgs(Items[itemCollIndex], DefaultCommand)); 1139 } 1140 1141 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SelectListItem"]/*' /> SelectListItem(int itemIndex, bool selectMore)1142 public bool SelectListItem(int itemIndex, bool selectMore) 1143 { 1144 EnsureItemLoaded (itemIndex); 1145 int itemCollIndex = TranslateVirtualItemIndex(itemIndex); 1146 1147 ObjectListSelectEventArgs args = new ObjectListSelectEventArgs( 1148 Items[itemCollIndex], 1149 selectMore); 1150 SelectedIndex = itemIndex; 1151 OnItemSelect(args); 1152 return args.UseDefaultHandling; 1153 } 1154 1155 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.PreShowItemCommands"]/*' /> PreShowItemCommands(int itemIndex)1156 public void PreShowItemCommands(int itemIndex) 1157 { 1158 // Called just before commands are shown for a given item. We call 1159 // an event handler that can modify (or even replace) the commands collection, 1160 // but first we mark the collection, and save it off, so that we can 1161 // save the state of the collection at this point. 1162 1163 if (_commands != null) 1164 { 1165 _globalCommands = _commands; 1166 _commands.GlobalStateSet(); 1167 } 1168 1169 SelectedIndex = itemIndex; 1170 1171 ObjectListShowCommandsEventArgs eventArgs = 1172 new ObjectListShowCommandsEventArgs(Selection, Commands); 1173 OnShowItemCommands(eventArgs); 1174 if (eventArgs.Commands != _commands) 1175 { 1176 _commands = eventArgs.Commands; 1177 } 1178 } 1179 EnsureItemLoaded(int virtualIndex)1180 private void EnsureItemLoaded(int virtualIndex) 1181 { 1182 Debug.Assert (virtualIndex >= 0, "virtualIndex < 0"); 1183 if (ItemCount > 0 && 1184 (_items == null || 1185 virtualIndex < Items.BaseIndex || 1186 Items.Count <= virtualIndex - Items.BaseIndex)) 1187 { 1188 OnLoadItems(new LoadItemsEventArgs(virtualIndex, 1)); 1189 } 1190 } 1191 TranslateVirtualItemIndex(int virtualIndex)1192 private int TranslateVirtualItemIndex(int virtualIndex) 1193 { 1194 Debug.Assert(ItemCount > 0 || Items.BaseIndex == 0); 1195 1196 // Translate virtual index to true index within collection. 1197 // If custom pagination is off, virtual index is the true index. 1198 return virtualIndex - Items.BaseIndex; 1199 } 1200 1201 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnLoadItems"]/*' /> OnLoadItems(LoadItemsEventArgs e)1202 protected override void OnLoadItems(LoadItemsEventArgs e) 1203 { 1204 // We should only load items if the base index has changed, or if 1205 // the desired items do not exist in the list. Otherwise, we are making 1206 // the app reload the same items over and over. 1207 1208 if (e.ItemIndex != Items.BaseIndex || e.ItemCount != Items.Count) 1209 { 1210 _loadingItems = true; 1211 Items.BaseIndex = e.ItemIndex; 1212 Items.Clear(); 1213 base.OnLoadItems(e); 1214 _loadingItems = false; 1215 } 1216 } 1217 1218 ///////////////////////////////////////////////////////////////////////// 1219 // STATE MANAGEMENT 1220 ///////////////////////////////////////////////////////////////////////// 1221 1222 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.TrackViewState"]/*' /> TrackViewState()1223 protected override void TrackViewState() 1224 { 1225 base.TrackViewState(); 1226 if (_fields != null) 1227 { 1228 ((IStateManager)_fields).TrackViewState(); 1229 } 1230 if (_commands != null) 1231 { 1232 ((IStateManager)_commands).TrackViewState(); 1233 } 1234 if (_items != null) 1235 { 1236 ((IStateManager)_items).TrackViewState(); 1237 } 1238 } 1239 1240 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SavePrivateViewState"]/*' /> SavePrivateViewState()1241 protected override Object SavePrivateViewState() 1242 { 1243 Object baseState = base.SavePrivateViewState(); 1244 if (ViewMode != ObjectListViewMode.List || _selectedIndexDirty) 1245 { 1246 return new Triplet(baseState, (int) ViewMode, SelectedIndex); 1247 } 1248 else if (baseState != null) 1249 { 1250 return baseState; 1251 } 1252 return null; 1253 } 1254 1255 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LoadPrivateViewState"]/*' /> LoadPrivateViewState(Object state)1256 protected override void LoadPrivateViewState(Object state) 1257 { 1258 if (state != null) 1259 { 1260 Triplet stateTriplet = state as Triplet; 1261 if (stateTriplet != null) 1262 { 1263 base.LoadPrivateViewState (stateTriplet.First); 1264 ObjectListViewMode originalViewMode = _viewMode; 1265 1266 // use private field because property get calls CreateChildControls. 1267 _viewMode = (ObjectListViewMode) stateTriplet.Second; 1268 1269 // use property to insure we load items if necessary and set selected index dirty. 1270 SelectedIndex = (int)stateTriplet.Third; 1271 1272 bool viewModeChanged = (originalViewMode != _viewMode); 1273 if (ChildControlsCreated && viewModeChanged) 1274 { 1275 // This is before items loaded in LVS, so we only do this if 1276 // child controls already created in init (e.g., no VS.) 1277 CreateChildControls (true); 1278 } 1279 } 1280 else 1281 { 1282 base.LoadPrivateViewState(state); 1283 } 1284 } 1285 } 1286 1287 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SaveViewState"]/*' /> SaveViewState()1288 protected override Object SaveViewState() 1289 { 1290 Object baseState, fieldsState, autoFieldsState, commandsState, itemsState; 1291 1292 Debug.Assert (Items != null, "get_Items should initialize Items collection."); 1293 int count = Items.Count; 1294 // HasControls implies DataBound on this or a prev req (but not converse). 1295 if (count > 0 || HasControls()) 1296 { 1297 ViewState[_itemCountViewStateKey] = count; 1298 } 1299 baseState = base.SaveViewState(); 1300 fieldsState = (_fields != null) ? ((IStateManager)_fields).SaveViewState() : null; 1301 autoFieldsState = SaveAutoFieldsState(); 1302 commandsState = (_commands != null) ? ((IStateManager)_commands).SaveViewState() : null; 1303 itemsState = (_items != null) ? ((IStateManager)_items).SaveViewState() : null; 1304 1305 if (itemsState != null || 1306 fieldsState != null || 1307 autoFieldsState != null || 1308 commandsState != null ) 1309 { 1310 return new Object[5] 1311 { 1312 baseState, 1313 fieldsState, 1314 autoFieldsState, 1315 commandsState, 1316 itemsState 1317 }; 1318 } 1319 else if (baseState != null) 1320 { 1321 return new Object[1] { baseState }; 1322 } 1323 return null; 1324 } 1325 1326 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LoadViewState"]/*' /> LoadViewState(Object savedState)1327 protected override void LoadViewState(Object savedState) 1328 { 1329 // copy locally (can change during Fields.LVS). 1330 bool ignoreFieldsItemsViewModeViewState = _ignoreFieldsItemsViewModeViewState; 1331 if (savedState != null) 1332 { 1333 Object[] state = (Object[])savedState; 1334 base.LoadViewState(state[0]); 1335 1336 if (state.Length > 1) 1337 { 1338 // Always load items after loading fields, because field changes can wipe out 1339 // items! 1340 if(!ignoreFieldsItemsViewModeViewState) 1341 { 1342 ((IStateManager)Fields).LoadViewState(state[1]); 1343 LoadAutoFieldsState(state[2]); 1344 } 1345 ((IStateManager)Commands).LoadViewState(state[3]); 1346 if(!ignoreFieldsItemsViewModeViewState) 1347 { 1348 ((IStateManager)Items).LoadViewState(state[4]); 1349 SelectItemIfLoaded(SelectedIndex); 1350 } 1351 } 1352 } 1353 } 1354 1355 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ViewMode"]/*' /> 1356 [ 1357 Bindable(false), 1358 Browsable(false), 1359 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 1360 ] 1361 public ObjectListViewMode ViewMode 1362 { 1363 get 1364 { 1365 return _viewMode; 1366 } 1367 set 1368 { 1369 if (SelectedIndex == -1 && value != ObjectListViewMode.List) 1370 { 1371 throw new Exception(SR.GetString( 1372 SR.ObjectList_CannotSetViewModeWithNoSelectedItem)); 1373 } 1374 if (value == ObjectListViewMode.List) 1375 { 1376 // Set pagination state changed to refresh pagination. 1377 Form.PaginationStateChanged = true; 1378 } 1379 _viewMode = value; 1380 CreateChildControls(true); 1381 } 1382 } 1383 1384 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DetailsCommandText"]/*' /> 1385 [ 1386 Bindable(true), 1387 Browsable(true), 1388 DefaultValue(""), 1389 MobileCategory(SR.Category_Appearance), 1390 MobileSysDescription(SR.ObjectList_DetailsCommandText), 1391 ] 1392 public String DetailsCommandText 1393 { 1394 get 1395 { 1396 String detailsCommandText = (String)ViewState["DetailsCommandText"]; 1397 return detailsCommandText != null ? detailsCommandText : String.Empty; 1398 } 1399 set 1400 { 1401 ViewState["DetailsCommandText"] = value; 1402 } 1403 } 1404 1405 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.BackCommandText"]/*' /> 1406 [ 1407 Bindable(true), 1408 Browsable(true), 1409 DefaultValue(""), 1410 MobileCategory(SR.Category_Appearance), 1411 MobileSysDescription(SR.ObjectList_BackCommandText), 1412 ] 1413 public String BackCommandText 1414 { 1415 get 1416 { 1417 String backCommandText = (String) ViewState["BackCommandText"]; 1418 return backCommandText != null ? backCommandText : String.Empty; 1419 } 1420 set 1421 { 1422 ViewState["BackCommandText"] = value; 1423 } 1424 } 1425 1426 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.MoreText"]/*' /> 1427 [ 1428 Bindable(true), 1429 Browsable(true), 1430 DefaultValue(""), 1431 MobileCategory(SR.Category_Appearance), 1432 MobileSysDescription(SR.ObjectList_MoreText) 1433 ] 1434 public String MoreText 1435 { 1436 get 1437 { 1438 String moreText = (String)ViewState["MoreText"]; 1439 return moreText != null ? moreText : String.Empty; 1440 } 1441 set 1442 { 1443 ViewState["MoreText"] = value; 1444 } 1445 } 1446 1447 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CommandStyle"]/*' /> 1448 [ 1449 DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 1450 MobileCategory(SR.Category_Style), 1451 MobileSysDescription(SR.ObjectList_CommandStyle), 1452 NotifyParentProperty(true) 1453 ] 1454 public Style CommandStyle 1455 { 1456 get 1457 { 1458 if (_commandStyle == null) 1459 { 1460 _commandStyle = new Style(); 1461 _commandStyle.SetControl(this); 1462 _commandStyle.StyleReference = "subcommand"; 1463 } 1464 return _commandStyle; 1465 } 1466 set 1467 { 1468 _commandStyle = value; 1469 } 1470 } 1471 1472 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LabelStyle"]/*' /> 1473 [ 1474 DefaultValue(null), 1475 DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 1476 MobileCategory(SR.Category_Style), 1477 MobileSysDescription(SR.ObjectList_LabelStyle), 1478 NotifyParentProperty(true) 1479 ] 1480 public Style LabelStyle 1481 { 1482 get 1483 { 1484 if (_labelStyle == null) 1485 { 1486 _labelStyle = new Style(); 1487 _labelStyle.SetControl(this); 1488 _labelStyle.StyleReference = "title"; 1489 } 1490 return _labelStyle; 1491 } 1492 set 1493 { 1494 _labelStyle = value; 1495 } 1496 } 1497 InvalidateParentStyles()1498 internal override void InvalidateParentStyles() 1499 { 1500 if (_commandStyle != null) 1501 { 1502 _commandStyle.InvalidateParentStyle(); 1503 } 1504 if (_labelStyle != null) 1505 { 1506 _labelStyle.InvalidateParentStyle(); 1507 } 1508 base.InvalidateParentStyles(); 1509 } 1510 InternalItemCountChangedHandler(int newItemCount)1511 internal override void InternalItemCountChangedHandler(int newItemCount) 1512 { 1513 if (newItemCount == 0) 1514 { 1515 ClearItemsAndControls(); 1516 } 1517 } 1518 ClearItemsAndControls()1519 private void ClearItemsAndControls() 1520 { 1521 ViewMode = ObjectListViewMode.List; 1522 SelectedIndex = -1; 1523 Items.Clear(); 1524 Controls.Clear(); 1525 } 1526 1527 // Wrapper to increase intelligibility at point of call. SelectItemIfLoaded(int virtualIndex)1528 private void SelectItemIfLoaded(int virtualIndex) 1529 { 1530 SetItemSelectedPropertyIfItemLoaded(virtualIndex, true); 1531 } 1532 1533 // Wrapper to increase intelligibility at point of call. DeselectItemIfLoaded(int virtualIndex)1534 private void DeselectItemIfLoaded(int virtualIndex) 1535 { 1536 SetItemSelectedPropertyIfItemLoaded(virtualIndex, false); 1537 } 1538 SetItemSelectedPropertyIfItemLoaded(int virtualIndex, bool newValue)1539 private void SetItemSelectedPropertyIfItemLoaded(int virtualIndex, bool newValue) 1540 { 1541 if (virtualIndex < 0) 1542 { 1543 return; 1544 } 1545 int physicalIndex = TranslateVirtualItemIndex(virtualIndex); 1546 if (physicalIndex >= 0 && physicalIndex < Items.Count) 1547 { 1548 Items[physicalIndex].Selected = newValue; 1549 } 1550 } 1551 1552 #region IPostBackEventHandler implementation IPostBackEventHandler.RaisePostBackEvent(String eventArgument)1553 void IPostBackEventHandler.RaisePostBackEvent(String eventArgument) { 1554 RaisePostBackEvent(eventArgument); 1555 } 1556 #endregion 1557 } 1558 1559 1560 /* 1561 * Control builder for object lists. 1562 * 1563 * Copyright (c) 2000 Microsoft Corporation 1564 */ 1565 1566 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectListControlBuilder"]/*' /> 1567 [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 1568 [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 1569 [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] 1570 public class ObjectListControlBuilder : MobileControlBuilder 1571 { 1572 /// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectListControlBuilder.GetChildControlType"]/*' /> GetChildControlType(String tagName, IDictionary attributes)1573 public override Type GetChildControlType(String tagName, IDictionary attributes) 1574 { 1575 if (String.Compare(tagName, "Field", StringComparison.OrdinalIgnoreCase) == 0) 1576 { 1577 return typeof(ObjectListField); 1578 } 1579 else if (String.Compare(tagName, "Command", StringComparison.OrdinalIgnoreCase) == 0) 1580 { 1581 return typeof(ObjectListCommand); 1582 } 1583 else 1584 { 1585 return base.GetChildControlType(tagName, attributes); 1586 } 1587 } 1588 } 1589 } 1590