1 //------------------------------------------------------------------------------ 2 // <copyright file="ObjectListCommandCollection.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.Diagnostics; 11 using System.Globalization; 12 using System.Web; 13 using System.Web.UI; 14 using System.Web.UI.WebControls; 15 using System.Web.UI.HtmlControls; 16 using System.Security.Permissions; 17 18 namespace System.Web.UI.MobileControls 19 { 20 /* 21 * Object List Command Collection class. 22 * 23 * Copyright (c) 2000 Microsoft Corporation 24 */ 25 26 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection"]/*' /> 27 [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 28 [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 29 [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.")] 30 public class ObjectListCommandCollection : ArrayListCollectionBase, IStateManager 31 { 32 // ObjectListCommandCollection has a special form of viewstate management. 33 // In normal operation, if you add, remove or modify commands in the 34 // collection, the results are saved as part of view state. 35 // 36 // However, when showing the commands for an item, the ObjectList control 37 // raises an event that allows the application to alter the commands 38 // specifically for the item. These changes are considered local to the 39 // item, and are not saved. 40 // 41 // To do this, the class uses a private state, declared in the MarkState 42 // enumeration below. The following sequence of events are used: 43 // 44 // 1) Class is created. MarkState is set to MarkState.NotMarked. 45 // 2) Class is initialized from persistent values. 46 // 3) Framework calls TrackViewState. MarkState is set to MarkState.MArked. 47 // 4) Properties can be changed. Changes are reflected in viewstate. 48 // 5) Just before raising the ShowItemCommands event, the ObjectList control 49 // calls GlobalStateSet. PreSaveViewState is called to create a 50 // snapshot of viewstate, and MarkState is set to MarkState.PostMarked. 51 // 6) If any changes are made after this, they will be ignored for view state 52 // purposes. 53 // 7) The framework calls SaveViewState. Instead of the current view state 54 // (which would include the changes made in Step 6), the snapshot view state 55 // from step 5 is returned. 56 57 private enum MarkState 58 { 59 NotMarked, 60 Marked, 61 PostMarked, 62 } 63 64 private MarkState _markState = MarkState.NotMarked; 65 private bool _dirty; 66 private String[] _savedState; 67 ObjectListCommandCollection()68 internal ObjectListCommandCollection() 69 { 70 } 71 72 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection.this"]/*' /> 73 public ObjectListCommand this[int index] 74 { 75 get 76 { 77 return (ObjectListCommand)Items[index]; 78 } 79 } 80 81 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection.Clear"]/*' /> Clear()82 public void Clear() 83 { 84 foreach (ObjectListCommand command in Items) 85 { 86 command.Owner = null; 87 } 88 Items.Clear(); 89 SetDirty(); 90 } 91 92 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection.Add"]/*' /> Add(ObjectListCommand command)93 public void Add(ObjectListCommand command) 94 { 95 AddAt(-1, command); 96 } 97 98 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection.AddAt"]/*' /> AddAt(int index, ObjectListCommand command)99 public void AddAt(int index, ObjectListCommand command) 100 { 101 if (index == -1) 102 { 103 Items.Add(command); 104 } 105 else 106 { 107 Items.Insert(index, command); 108 } 109 command.Owner = this; 110 SetDirty(); 111 } 112 113 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection.Remove"]/*' /> Remove(String s)114 public void Remove(String s) 115 { 116 RemoveAt(IndexOf(s)); 117 } 118 119 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection.RemoveAt"]/*' /> RemoveAt(int index)120 public void RemoveAt(int index) 121 { 122 (this[index]).Owner = null; 123 Items.RemoveAt(index); 124 SetDirty(); 125 } 126 127 /// <include file='doc\ObjectListCommandCollection.uex' path='docs/doc[@for="ObjectListCommandCollection.IndexOf"]/*' /> IndexOf(String s)128 public int IndexOf(String s) 129 { 130 int index = 0; 131 foreach (ObjectListCommand command in Items) 132 { 133 if (String.Compare(command.Name, s, StringComparison.OrdinalIgnoreCase) == 0) 134 { 135 return index; 136 } 137 index++; 138 } 139 return -1; 140 } 141 GlobalStateSet()142 internal void GlobalStateSet() 143 { 144 // Base commands have been set. From here, commands will only be 145 // modified on a per-item, non-persistent basis. 146 147 PreSaveViewState(); 148 _markState = MarkState.PostMarked; 149 } 150 SetDirty()151 internal void SetDirty() 152 { 153 if (_markState == MarkState.Marked) 154 { 155 _dirty = true; 156 } 157 } 158 159 ///////////////////////////////////////////////////////////////////////// 160 // STATE MANAGEMENT 161 ///////////////////////////////////////////////////////////////////////// 162 PreSaveViewState()163 private void PreSaveViewState() 164 { 165 if (_dirty) 166 { 167 ArrayList commands = Items; 168 _savedState = new String[commands.Count * 2]; 169 int i = 0; 170 foreach (ObjectListCommand command in commands) 171 { 172 _savedState[i] = command.Name; 173 _savedState[i + 1] = command.Text; 174 i += 2; 175 } 176 } 177 else 178 { 179 _savedState = null; 180 } 181 } 182 183 /// <internalonly/> 184 protected bool IsTrackingViewState 185 { 186 get 187 { 188 return _markState != MarkState.NotMarked; 189 } 190 } 191 192 /// <internalonly/> TrackViewState()193 protected void TrackViewState() 194 { 195 _markState = MarkState.Marked; 196 } 197 198 /// <internalonly/> LoadViewState(Object state)199 protected void LoadViewState(Object state) 200 { 201 if (state != null) 202 { 203 String[] commandStates = (String[])state; 204 int count = commandStates.Length; 205 Clear(); 206 for (int i = 0; i < count; i += 2) 207 { 208 Add(new ObjectListCommand(commandStates[i], commandStates[i + 1])); 209 } 210 } 211 } 212 213 /// <internalonly/> SaveViewState()214 protected Object SaveViewState() 215 { 216 if (_markState == MarkState.Marked) 217 { 218 PreSaveViewState(); 219 } 220 return _savedState; 221 } 222 223 #region Implementation of IStateManager 224 /// <internalonly/> 225 bool IStateManager.IsTrackingViewState { 226 get { 227 return IsTrackingViewState; 228 } 229 } 230 231 /// <internalonly/> IStateManager.LoadViewState(object state)232 void IStateManager.LoadViewState(object state) { 233 LoadViewState(state); 234 } 235 236 /// <internalonly/> IStateManager.TrackViewState()237 void IStateManager.TrackViewState() { 238 TrackViewState(); 239 } 240 241 /// <internalonly/> IStateManager.SaveViewState()242 object IStateManager.SaveViewState() { 243 return SaveViewState(); 244 } 245 #endregion 246 } 247 } 248 249 250