1 //
2 // System.Web.UI.WebControls.DetailsView.cs
3 //
4 // Authors:
5 //	Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // (C) 2005-2010 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 
29 using System;
30 using System.Collections;
31 using System.Collections.Specialized;
32 using System.ComponentModel;
33 using System.Web.UI;
34 using System.Security.Permissions;
35 using System.Text;
36 using System.IO;
37 using System.Reflection;
38 
39 namespace System.Web.UI.WebControls
40 {
41 	[SupportsEventValidation]
42 	[ToolboxDataAttribute ("<{0}:DetailsView runat=\"server\" Width=\"125px\" Height=\"50px\"></{0}:DetailsView>")]
43 	[DesignerAttribute ("System.Web.UI.Design.WebControls.DetailsViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44 	[ControlValuePropertyAttribute ("SelectedValue")]
45 	[DefaultEventAttribute ("PageIndexChanging")]
46 	[DataKeyProperty ("DataKey")]
47 	[AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48 	[AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49 	public class DetailsView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer
50 		, IDataBoundItemControl, IDataBoundControl, IFieldControl
51 	{
52 		object dataItem;
53 
54 		Table table;
55 		DetailsViewRowCollection rows;
56 		DetailsViewRow headerRow;
57 		DetailsViewRow footerRow;
58 		DetailsViewRow bottomPagerRow;
59 		DetailsViewRow topPagerRow;
60 
61 		IOrderedDictionary currentEditRowKeys;
62 		IOrderedDictionary currentEditNewValues;
63 		IOrderedDictionary currentEditOldValues;
64 
65 		ITemplate pagerTemplate;
66 		ITemplate emptyDataTemplate;
67 		ITemplate headerTemplate;
68 		ITemplate footerTemplate;
69 
70 		PropertyDescriptor[] cachedKeyProperties;
71 		readonly string[] emptyKeys = new string[0];
72 		readonly string unhandledEventExceptionMessage = "The DetailsView '{0}' fired event {1} which wasn't handled.";
73 
74 		// View state
75 		DataControlFieldCollection columns;
76 		PagerSettings pagerSettings;
77 
78 		TableItemStyle alternatingRowStyle;
79 		TableItemStyle editRowStyle;
80 		TableItemStyle insertRowStyle;
81 		TableItemStyle emptyDataRowStyle;
82 		TableItemStyle footerStyle;
83 		TableItemStyle headerStyle;
84 		TableItemStyle pagerStyle;
85 		TableItemStyle rowStyle;
86 		TableItemStyle commandRowStyle;
87 		TableItemStyle fieldHeaderStyle;
88 
89 		IOrderedDictionary _keyTable;
90 		DataKey key;
91 		DataKey oldEditValues;
92 		AutoGeneratedFieldProperties[] autoFieldProperties;
93 
94 		static readonly object PageIndexChangedEvent = new object();
95 		static readonly object PageIndexChangingEvent = new object();
96 		static readonly object ItemCommandEvent = new object();
97 		static readonly object ItemCreatedEvent = new object();
98 		static readonly object ItemDeletedEvent = new object();
99 		static readonly object ItemDeletingEvent = new object();
100 		static readonly object ItemInsertedEvent = new object();
101 		static readonly object ItemInsertingEvent = new object();
102 		static readonly object ModeChangingEvent = new object();
103 		static readonly object ModeChangedEvent = new object();
104 		static readonly object ItemUpdatedEvent = new object();
105 		static readonly object ItemUpdatingEvent = new object();
106 
107 		// Control state
108 		int pageIndex;
109 		DetailsViewMode currentMode = DetailsViewMode.ReadOnly;
110 		bool hasCurrentMode;
111 		int pageCount;
112 
DetailsView()113 		public DetailsView ()
114 		{
115 			rows = new DetailsViewRowCollection (new ArrayList ());
116 		}
117 
118 		public event EventHandler PageIndexChanged {
119 			add { Events.AddHandler (PageIndexChangedEvent, value); }
120 			remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
121 		}
122 
123 		public event DetailsViewPageEventHandler PageIndexChanging {
124 			add { Events.AddHandler (PageIndexChangingEvent, value); }
125 			remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
126 		}
127 
128 		public event DetailsViewCommandEventHandler ItemCommand {
129 			add { Events.AddHandler (ItemCommandEvent, value); }
130 			remove { Events.RemoveHandler (ItemCommandEvent, value); }
131 		}
132 
133 		public event EventHandler ItemCreated {
134 			add { Events.AddHandler (ItemCreatedEvent, value); }
135 			remove { Events.RemoveHandler (ItemCreatedEvent, value); }
136 		}
137 
138 		public event DetailsViewDeletedEventHandler ItemDeleted {
139 			add { Events.AddHandler (ItemDeletedEvent, value); }
140 			remove { Events.RemoveHandler (ItemDeletedEvent, value); }
141 		}
142 
143 		public event DetailsViewDeleteEventHandler ItemDeleting {
144 			add { Events.AddHandler (ItemDeletingEvent, value); }
145 			remove { Events.RemoveHandler (ItemDeletingEvent, value); }
146 		}
147 
148 		public event DetailsViewInsertedEventHandler ItemInserted {
149 			add { Events.AddHandler (ItemInsertedEvent, value); }
150 			remove { Events.RemoveHandler (ItemInsertedEvent, value); }
151 		}
152 
153 		public event DetailsViewInsertEventHandler ItemInserting {
154 			add { Events.AddHandler (ItemInsertingEvent, value); }
155 			remove { Events.RemoveHandler (ItemInsertingEvent, value); }
156 		}
157 
158 		public event DetailsViewModeEventHandler ModeChanging {
159 			add { Events.AddHandler (ModeChangingEvent, value); }
160 			remove { Events.RemoveHandler (ModeChangingEvent, value); }
161 		}
162 
163 		public event EventHandler ModeChanged {
164 			add { Events.AddHandler (ModeChangedEvent, value); }
165 			remove { Events.RemoveHandler (ModeChangedEvent, value); }
166 		}
167 
168 		public event DetailsViewUpdatedEventHandler ItemUpdated {
169 			add { Events.AddHandler (ItemUpdatedEvent, value); }
170 			remove { Events.RemoveHandler (ItemUpdatedEvent, value); }
171 		}
172 
173 		public event DetailsViewUpdateEventHandler ItemUpdating {
174 			add { Events.AddHandler (ItemUpdatingEvent, value); }
175 			remove { Events.RemoveHandler (ItemUpdatingEvent, value); }
176 		}
177 
OnPageIndexChanged(EventArgs e)178 		protected virtual void OnPageIndexChanged (EventArgs e)
179 		{
180 			if (Events != null) {
181 				EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
182 				if (eh != null) eh (this, e);
183 			}
184 		}
185 
OnPageIndexChanging(DetailsViewPageEventArgs e)186 		protected virtual void OnPageIndexChanging (DetailsViewPageEventArgs e)
187 		{
188 			if (Events != null) {
189 				DetailsViewPageEventHandler eh = (DetailsViewPageEventHandler) Events [PageIndexChangingEvent];
190 				if (eh != null) {
191 					eh (this, e);
192 					return;
193 				}
194 			}
195 			if (!IsBoundUsingDataSourceID)
196 				throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "PageIndexChanging"));
197 		}
198 
OnItemCommand(DetailsViewCommandEventArgs e)199 		protected virtual void OnItemCommand (DetailsViewCommandEventArgs e)
200 		{
201 			if (Events != null) {
202 				DetailsViewCommandEventHandler eh = (DetailsViewCommandEventHandler) Events [ItemCommandEvent];
203 				if (eh != null) eh (this, e);
204 			}
205 		}
206 
OnItemCreated(EventArgs e)207 		protected virtual void OnItemCreated (EventArgs e)
208 		{
209 			if (Events != null) {
210 				EventHandler eh = (EventHandler) Events [ItemCreatedEvent];
211 				if (eh != null) eh (this, e);
212 			}
213 		}
214 
OnItemDeleted(DetailsViewDeletedEventArgs e)215 		protected virtual void OnItemDeleted (DetailsViewDeletedEventArgs e)
216 		{
217 			if (Events != null) {
218 				DetailsViewDeletedEventHandler eh = (DetailsViewDeletedEventHandler) Events [ItemDeletedEvent];
219 				if (eh != null) eh (this, e);
220 			}
221 		}
222 
OnItemInserted(DetailsViewInsertedEventArgs e)223 		protected virtual void OnItemInserted (DetailsViewInsertedEventArgs e)
224 		{
225 			if (Events != null) {
226 				DetailsViewInsertedEventHandler eh = (DetailsViewInsertedEventHandler) Events [ItemInsertedEvent];
227 				if (eh != null) eh (this, e);
228 			}
229 		}
230 
OnItemInserting(DetailsViewInsertEventArgs e)231 		protected virtual void OnItemInserting (DetailsViewInsertEventArgs e)
232 		{
233 			if (Events != null) {
234 				DetailsViewInsertEventHandler eh = (DetailsViewInsertEventHandler) Events [ItemInsertingEvent];
235 				if (eh != null) {
236 					eh (this, e);
237 					return;
238 				}
239 			}
240 			if (!IsBoundUsingDataSourceID)
241 				throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemInserting"));
242 		}
243 
OnItemDeleting(DetailsViewDeleteEventArgs e)244 		protected virtual void OnItemDeleting (DetailsViewDeleteEventArgs e)
245 		{
246 			if (Events != null) {
247 				DetailsViewDeleteEventHandler eh = (DetailsViewDeleteEventHandler) Events [ItemDeletingEvent];
248 				if (eh != null) {
249 					eh (this, e);
250 					return;
251 				}
252 			}
253 			if (!IsBoundUsingDataSourceID)
254 				throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemDeleting"));
255 		}
256 
OnModeChanged(EventArgs e)257 		protected virtual void OnModeChanged (EventArgs e)
258 		{
259 			if (Events != null) {
260 				EventHandler eh = (EventHandler) Events [ModeChangedEvent];
261 				if (eh != null) eh (this, e);
262 			}
263 		}
264 
OnModeChanging(DetailsViewModeEventArgs e)265 		protected virtual void OnModeChanging (DetailsViewModeEventArgs e)
266 		{
267 			if (Events != null) {
268 				DetailsViewModeEventHandler eh = (DetailsViewModeEventHandler) Events [ModeChangingEvent];
269 				if (eh != null) {
270 					eh (this, e);
271 					return;
272 				}
273 			}
274 			if (!IsBoundUsingDataSourceID)
275 				throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ModeChanging"));
276 		}
277 
OnItemUpdated(DetailsViewUpdatedEventArgs e)278 		protected virtual void OnItemUpdated (DetailsViewUpdatedEventArgs e)
279 		{
280 			if (Events != null) {
281 				DetailsViewUpdatedEventHandler eh = (DetailsViewUpdatedEventHandler) Events [ItemUpdatedEvent];
282 				if (eh != null) eh (this, e);
283 			}
284 		}
285 
OnItemUpdating(DetailsViewUpdateEventArgs e)286 		protected virtual void OnItemUpdating (DetailsViewUpdateEventArgs e)
287 		{
288 			if (Events != null) {
289 				DetailsViewUpdateEventHandler eh = (DetailsViewUpdateEventHandler) Events [ItemUpdatingEvent];
290 				if (eh != null) {
291 					eh (this, e);
292 					return;
293 				}
294 			}
295 			if (!IsBoundUsingDataSourceID)
296 				throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemUpdating"));
297 		}
298 
299 		DataBoundControlMode IDataBoundItemControl.Mode {
300 			get {
301 				switch (CurrentMode) {
302 					case DetailsViewMode.ReadOnly:
303 						return DataBoundControlMode.ReadOnly;
304 
305 					case DetailsViewMode.Edit:
306 						return DataBoundControlMode.Edit;
307 
308 					case DetailsViewMode.Insert:
309 						return DataBoundControlMode.Insert;
310 
311 					default:
312 						throw new InvalidOperationException (String.Format ("Unsupported CurrentMode value '{0}'", CurrentMode));
313 				}
314 			}
315 		}
316 
317 		IDataSource IDataBoundControl.DataSourceObject {
318 			get { return base.DataSourceObject; }
319 		}
320 
321 		IAutoFieldGenerator IFieldControl.FieldsGenerator {
322 			get {
323 				throw new NotImplementedException ();
324 			}
325 
326 			set {
327 				throw new NotImplementedException ();
328 			}
329 		}
330 		[WebCategoryAttribute ("Paging")]
331 		[DefaultValueAttribute (false)]
332 		public virtual bool AllowPaging {
333 			get {
334 				object ob = ViewState ["AllowPaging"];
335 				if (ob != null)
336 					return (bool) ob;
337 				return false;
338 			}
339 			set {
340 				ViewState ["AllowPaging"] = value;
341 				RequireBinding ();
342 			}
343 		}
344 
345 		[DefaultValueAttribute (null)]
346 		[WebCategoryAttribute ("Styles")]
347 		[PersistenceMode (PersistenceMode.InnerProperty)]
348 		[NotifyParentProperty (true)]
349 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
350 		public TableItemStyle AlternatingRowStyle {
351 			get {
352 				if (alternatingRowStyle == null) {
353 					alternatingRowStyle = new TableItemStyle ();
354 					if (IsTrackingViewState)
355 						alternatingRowStyle.TrackViewState();
356 				}
357 				return alternatingRowStyle;
358 			}
359 		}
360 
361 		[WebCategoryAttribute ("Behavior")]
362 		[DefaultValueAttribute (false)]
363 		public virtual bool AutoGenerateEditButton {
364 			get {
365 				object ob = ViewState ["AutoGenerateEditButton"];
366 				if (ob != null)
367 					return (bool) ob;
368 				return false;
369 			}
370 			set {
371 				ViewState ["AutoGenerateEditButton"] = value;
372 				RequireBinding ();
373 			}
374 		}
375 
376 		[WebCategoryAttribute ("Behavior")]
377 		[DefaultValueAttribute (false)]
378 		public virtual bool AutoGenerateDeleteButton {
379 			get {
380 				object ob = ViewState ["AutoGenerateDeleteButton"];
381 				if (ob != null)
382 					return (bool) ob;
383 				return false;
384 			}
385 			set {
386 				ViewState ["AutoGenerateDeleteButton"] = value;
387 				RequireBinding ();
388 			}
389 		}
390 
391 		[WebCategoryAttribute ("Behavior")]
392 		[DefaultValueAttribute (false)]
393 		public virtual bool AutoGenerateInsertButton {
394 			get {
395 				object ob = ViewState ["AutoGenerateInsertButton"];
396 				if (ob != null)
397 					return (bool) ob;
398 				return false;
399 			}
400 			set {
401 				ViewState ["AutoGenerateInsertButton"] = value;
402 				RequireBinding ();
403 			}
404 		}
405 
406 		[WebCategoryAttribute ("Behavior")]
407 		[DefaultValueAttribute (true)]
408 		public virtual bool AutoGenerateRows {
409 			get {
410 				object ob = ViewState ["AutoGenerateRows"];
411 				if (ob != null)
412 					return (bool) ob;
413 				return true;
414 			}
415 			set {
416 				ViewState ["AutoGenerateRows"] = value;
417 				RequireBinding ();
418 			}
419 		}
420 
421 		[UrlPropertyAttribute]
422 		[WebCategoryAttribute ("Appearance")]
423 		[DefaultValueAttribute ("")]
424 		[EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
425 		public virtual string BackImageUrl {
426 			get {
427 				if (ControlStyleCreated)
428 					return ((TableStyle) ControlStyle).BackImageUrl;
429 				return String.Empty;
430 			}
431 			set {
432 				((TableStyle) ControlStyle).BackImageUrl = value;
433 			}
434 		}
435 
436 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
437 		[BrowsableAttribute (false)]
438 		public virtual DetailsViewRow BottomPagerRow {
439 			get {
440 				EnsureChildControls ();
441 				return bottomPagerRow;
442 			}
443 		}
444 
445 		[WebCategoryAttribute ("Accessibility")]
446 		[DefaultValueAttribute ("")]
447 		[LocalizableAttribute (true)]
448 		public virtual string Caption {
449 			get {
450 				object ob = ViewState ["Caption"];
451 				if (ob != null)
452 					return (string) ob;
453 				return String.Empty;
454 			}
455 			set {
456 				ViewState ["Caption"] = value;
457 				RequireBinding ();
458 			}
459 		}
460 
461 		[WebCategoryAttribute ("Accessibility")]
462 		[DefaultValueAttribute (TableCaptionAlign.NotSet)]
463 		public virtual TableCaptionAlign CaptionAlign {
464 			get {
465 				object o = ViewState ["CaptionAlign"];
466 				if(o != null)
467 					return (TableCaptionAlign) o;
468 				return TableCaptionAlign.NotSet;
469 			}
470 			set {
471 				ViewState ["CaptionAlign"] = value;
472 				RequireBinding ();
473 			}
474 		}
475 
476 		[WebCategoryAttribute ("Layout")]
477 		[DefaultValueAttribute (-1)]
478 		public virtual int CellPadding {
479 			get {
480 				if (ControlStyleCreated)
481 					return ((TableStyle) ControlStyle).CellPadding;
482 				return -1;
483 			}
484 			set { ((TableStyle) ControlStyle).CellPadding = value; }
485 		}
486 
487 		[WebCategoryAttribute ("Layout")]
488 		[DefaultValueAttribute (0)]
489 		public virtual int CellSpacing {
490 			get {
491 				if (ControlStyleCreated)
492 					return ((TableStyle) ControlStyle).CellSpacing;
493 				return 0;
494 			}
495 			set { ((TableStyle) ControlStyle).CellSpacing = value; }
496 		}
497 
498 		[DefaultValueAttribute (null)]
499 		[WebCategoryAttribute ("Styles")]
500 		[PersistenceMode (PersistenceMode.InnerProperty)]
501 		[NotifyParentProperty (true)]
502 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
503 		public TableItemStyle CommandRowStyle {
504 			get {
505 				if (commandRowStyle == null) {
506 					commandRowStyle = new TableItemStyle ();
507 					if (IsTrackingViewState)
508 						commandRowStyle.TrackViewState();
509 				}
510 				return commandRowStyle;
511 			}
512 		}
513 
514 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
515 		[BrowsableAttribute (false)]
516 		public DetailsViewMode CurrentMode {
517 			get { return hasCurrentMode ? currentMode : DefaultMode; }
518 
519 			private set {
520 				hasCurrentMode = true;
521 				currentMode = value;
522 			}
523 		}
524 
525 		DetailsViewMode defaultMode = DetailsViewMode.ReadOnly;
526 		[DefaultValueAttribute (DetailsViewMode.ReadOnly)]
527 		[WebCategoryAttribute ("Behavior")]
528 		public virtual DetailsViewMode DefaultMode {
529 			get { return defaultMode; }
530 			set {
531 				defaultMode = value;
532 				RequireBinding ();
533 			}
534 		}
535 
536 		[EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
537 		[MergablePropertyAttribute (false)]
538 		[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
539 		[DefaultValueAttribute (null)]
540 		[WebCategoryAttribute ("Misc")]
541 		public virtual DataControlFieldCollection Fields {
542 			get {
543 				if (columns == null) {
544 					columns = new DataControlFieldCollection ();
545 					columns.FieldsChanged += new EventHandler (OnFieldsChanged);
546 					if (IsTrackingViewState)
547 						((IStateManager)columns).TrackViewState ();
548 				}
549 				return columns;
550 			}
551 		}
552 
553 		string[] dataKeyNames = null;
554 
555 		[DefaultValueAttribute (null)]
556 		[WebCategoryAttribute ("Data")]
557 		[TypeConverter (typeof(StringArrayConverter))]
558 		[EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
559 		public virtual string[] DataKeyNames {
560 			get {
561 				if (dataKeyNames == null)
562 					return emptyKeys;
563 				else
564 					return dataKeyNames;
565 			}
566 			set {
567 				dataKeyNames = value;
568 				RequireBinding ();
569 			}
570 		}
571 
572 		IOrderedDictionary KeyTable {
573 			get {
574 				if (_keyTable == null)
575 					_keyTable = new OrderedDictionary (DataKeyNames.Length);
576 				return _keyTable;
577 			}
578 		}
579 
580 		[BrowsableAttribute (false)]
581 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
582 		public virtual DataKey DataKey {
583 			get {
584 				if (key == null)
585 					key = new DataKey (KeyTable);
586 				return key;
587 			}
588 		}
589 
590 		DataKey OldEditValues {
591 			get {
592 				if (oldEditValues == null)
593 					oldEditValues = new DataKey (new OrderedDictionary ());
594 				return oldEditValues;
595 			}
596 		}
597 
598 		[WebCategoryAttribute ("Styles")]
599 		[PersistenceMode (PersistenceMode.InnerProperty)]
600 		[NotifyParentProperty (true)]
601 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
602 		[DefaultValueAttribute (null)]
603 		public TableItemStyle EditRowStyle {
604 			get {
605 				if (editRowStyle == null) {
606 					editRowStyle = new TableItemStyle ();
607 					if (IsTrackingViewState)
608 						editRowStyle.TrackViewState();
609 				}
610 				return editRowStyle;
611 			}
612 		}
613 
614 		[WebCategoryAttribute ("Styles")]
615 		[PersistenceMode (PersistenceMode.InnerProperty)]
616 		[NotifyParentProperty (true)]
617 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
618 		[DefaultValueAttribute (null)]
619 		public TableItemStyle EmptyDataRowStyle {
620 			get {
621 				if (emptyDataRowStyle == null) {
622 					emptyDataRowStyle = new TableItemStyle ();
623 					if (IsTrackingViewState)
624 						emptyDataRowStyle.TrackViewState();
625 				}
626 				return emptyDataRowStyle;
627 			}
628 		}
629 
630 		[DefaultValue (null)]
631 		[TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
632 		[PersistenceMode (PersistenceMode.InnerProperty)]
633 		[Browsable (false)]
634 		public virtual ITemplate EmptyDataTemplate {
635 			get { return emptyDataTemplate; }
636 			set { emptyDataTemplate = value; }
637 		}
638 
639 		[LocalizableAttribute (true)]
640 		[WebCategoryAttribute ("Appearance")]
641 		[DefaultValueAttribute ("")]
642 		public virtual string EmptyDataText {
643 			get {
644 				object ob = ViewState ["EmptyDataText"];
645 				if (ob != null)
646 					return (string) ob;
647 				return String.Empty;
648 			}
649 			set {
650 				ViewState ["EmptyDataText"] = value;
651 				RequireBinding ();
652 			}
653 		}
654 
655 		[WebCategoryAttribute ("Behavior")]
656 		[DefaultValueAttribute (false)]
657 		public virtual bool EnablePagingCallbacks {
658 			get {
659 				object ob = ViewState ["EnablePagingCallbacks"];
660 				if (ob != null)
661 					return (bool) ob;
662 				return false;
663 			}
664 			set {
665 				ViewState ["EnablePagingCallbacks"] = value;
666 				RequireBinding ();
667 			}
668 		}
669 
670 		[WebCategoryAttribute ("Styles")]
671 		[PersistenceMode (PersistenceMode.InnerProperty)]
672 		[NotifyParentProperty (true)]
673 		[DefaultValue (null)]
674 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
675 		public TableItemStyle FieldHeaderStyle {
676 			get {
677 				if (fieldHeaderStyle == null) {
678 					fieldHeaderStyle = new TableItemStyle ();
679 					if (IsTrackingViewState)
680 						fieldHeaderStyle.TrackViewState();
681 				}
682 				return fieldHeaderStyle;
683 			}
684 		}
685 
686 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
687 		[BrowsableAttribute (false)]
688 		public virtual DetailsViewRow FooterRow {
689 			get {
690 				EnsureChildControls ();
691 				return footerRow;
692 			}
693 		}
694 
695 		[DefaultValue (null)]
696 		[TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
697 		[PersistenceMode (PersistenceMode.InnerProperty)]
698 		[Browsable (false)]
699 		public virtual ITemplate FooterTemplate {
700 			get { return footerTemplate; }
701 			set { footerTemplate = value; }
702 		}
703 
704 		[LocalizableAttribute (true)]
705 		[WebCategoryAttribute ("Appearance")]
706 		[DefaultValueAttribute ("")]
707 		public virtual string FooterText {
708 			get {
709 				object ob = ViewState ["FooterText"];
710 				if (ob != null)
711 					return (string) ob;
712 				return String.Empty;
713 			}
714 			set {
715 				ViewState ["FooterText"] = value;
716 				RequireBinding ();
717 			}
718 		}
719 
720 		[WebCategoryAttribute ("Styles")]
721 		[PersistenceMode (PersistenceMode.InnerProperty)]
722 		[NotifyParentProperty (true)]
723 		[DefaultValue (null)]
724 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
725 		public TableItemStyle FooterStyle {
726 			get {
727 				if (footerStyle == null) {
728 					footerStyle = new TableItemStyle ();
729 					if (IsTrackingViewState)
730 						footerStyle.TrackViewState();
731 				}
732 				return footerStyle;
733 			}
734 		}
735 
736 		[WebCategoryAttribute ("Appearance")]
737 		[DefaultValueAttribute (GridLines.Both)]
738 		public virtual GridLines GridLines {
739 			get {
740 				if (ControlStyleCreated)
741 					return ((TableStyle) ControlStyle).GridLines;
742 				return GridLines.Both;
743 			}
744 			set { ((TableStyle) ControlStyle).GridLines = value; }
745 		}
746 
747 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
748 		[BrowsableAttribute (false)]
749 		public virtual DetailsViewRow HeaderRow {
750 			get {
751 				EnsureChildControls ();
752 				return headerRow;
753 			}
754 		}
755 
756 		[WebCategoryAttribute ("Styles")]
757 		[PersistenceMode (PersistenceMode.InnerProperty)]
758 		[NotifyParentProperty (true)]
759 		[DefaultValue (null)]
760 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
761 		public TableItemStyle HeaderStyle {
762 			get {
763 				if (headerStyle == null) {
764 					headerStyle = new TableItemStyle ();
765 					if (IsTrackingViewState)
766 						headerStyle.TrackViewState();
767 				}
768 				return headerStyle;
769 			}
770 		}
771 
772 		[DefaultValue (null)]
773 		[TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
774 		[PersistenceMode (PersistenceMode.InnerProperty)]
775 		[Browsable (false)]
776 		public virtual ITemplate HeaderTemplate {
777 			get { return headerTemplate; }
778 			set { headerTemplate = value; }
779 		}
780 
781 		[LocalizableAttribute (true)]
782 		[WebCategoryAttribute ("Appearance")]
783 		[DefaultValueAttribute ("")]
784 		public virtual string HeaderText {
785 			get {
786 				object ob = ViewState ["HeaderText"];
787 				if (ob != null)
788 					return (string) ob;
789 				return String.Empty;
790 			}
791 			set {
792 				ViewState ["HeaderText"] = value;
793 				RequireBinding ();
794 			}
795 		}
796 
797 		[Category ("Layout")]
798 		[DefaultValueAttribute (HorizontalAlign.NotSet)]
799 		public virtual HorizontalAlign HorizontalAlign {
800 			get {
801 				if (ControlStyleCreated)
802 					return ((TableStyle) ControlStyle).HorizontalAlign;
803 				return HorizontalAlign.NotSet;
804 			}
805 			set { ((TableStyle) ControlStyle).HorizontalAlign = value; }
806 		}
807 
808 		[WebCategoryAttribute ("Styles")]
809 		[PersistenceMode (PersistenceMode.InnerProperty)]
810 		[NotifyParentProperty (true)]
811 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
812 		[DefaultValueAttribute (null)]
813 		public TableItemStyle InsertRowStyle {
814 			get {
815 				if (insertRowStyle == null) {
816 					insertRowStyle = new TableItemStyle ();
817 					if (IsTrackingViewState)
818 						insertRowStyle.TrackViewState();
819 				}
820 				return insertRowStyle;
821 			}
822 		}
823 
824 		[BrowsableAttribute (false)]
825 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
826 		public virtual int PageCount {
827 			get { return pageCount; }
828 			private set { pageCount = value; }
829 		}
830 
831 		[WebCategoryAttribute ("Paging")]
832 		[BindableAttribute (true, BindingDirection.OneWay)]
833 		[DefaultValueAttribute (0)]
834 		public virtual int PageIndex {
835 			get {
836 				if (CurrentMode == DetailsViewMode.Insert)
837 					return -1;
838 				return pageIndex;
839 			}
840 			set {
841 				if (value < -1)
842 					throw new ArgumentOutOfRangeException ("PageIndex must be non-negative");
843 				if (pageIndex == value || value == -1)
844 					return;
845 				pageIndex = value;
846 				RequireBinding ();
847 			}
848 		}
849 
850 		[WebCategoryAttribute ("Paging")]
851 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
852 		[NotifyParentPropertyAttribute (true)]
853 		[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
854 		public virtual PagerSettings PagerSettings {
855 			get {
856 				if (pagerSettings == null) {
857 					pagerSettings = new PagerSettings (this);
858 					if (IsTrackingViewState)
859 						((IStateManager)pagerSettings).TrackViewState ();
860 				}
861 				return pagerSettings;
862 			}
863 		}
864 
865 		[WebCategoryAttribute ("Styles")]
866 		[PersistenceMode (PersistenceMode.InnerProperty)]
867 		[NotifyParentProperty (true)]
868 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
869 		public TableItemStyle PagerStyle {
870 			get {
871 				if (pagerStyle == null) {
872 					pagerStyle = new TableItemStyle ();
873 					if (IsTrackingViewState)
874 						pagerStyle.TrackViewState();
875 				}
876 				return pagerStyle;
877 			}
878 		}
879 
880 
881 		[DefaultValue (null)]
882 		[TemplateContainer (typeof (DetailsView), BindingDirection.OneWay)]
883 		[PersistenceMode (PersistenceMode.InnerProperty)]
884 		[Browsable (false)]
885 		public virtual ITemplate PagerTemplate {
886 			get { return pagerTemplate; }
887 			set { pagerTemplate = value; }
888 		}
889 
890 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
891 		[BrowsableAttribute (false)]
892 		public virtual DetailsViewRowCollection Rows {
893 			get {
894 				EnsureChildControls ();
895 				return rows;
896 			}
897 		}
898 
899 		[BrowsableAttribute(false)]
900 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
901 		public IAutoFieldGenerator RowsGenerator {
902 			get;
903 			set;
904 		}
905 
906 		[WebCategoryAttribute ("Styles")]
907 		[PersistenceMode (PersistenceMode.InnerProperty)]
908 		[NotifyParentProperty (true)]
909 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
910 		[DefaultValue (null)]
911 		public TableItemStyle RowStyle {
912 			get {
913 				if (rowStyle == null) {
914 					rowStyle = new TableItemStyle ();
915 					if (IsTrackingViewState)
916 						rowStyle.TrackViewState();
917 				}
918 				return rowStyle;
919 			}
920 		}
921 
922 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
923 		[BrowsableAttribute (false)]
924 		public object SelectedValue {
925 			get { return DataKey.Value; }
926 		}
927 
928 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
929 		[BrowsableAttribute (false)]
930 		public virtual DetailsViewRow TopPagerRow {
931 			get {
932 				EnsureChildControls ();
933 				return topPagerRow;
934 			}
935 		}
936 
937 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
938 		[BrowsableAttribute (false)]
939 		public virtual object DataItem {
940 			get {
941 				return dataItem;
942 			}
943 		}
944 
945 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
946 		[BrowsableAttribute (false)]
947 		public int DataItemCount {
948 			get { return PageCount; }
949 		}
950 
951 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
952 		[BrowsableAttribute (false)]
953 		public virtual int DataItemIndex {
954 			get { return PageIndex; }
955 		}
956 
957 		int IDataItemContainer.DisplayIndex {
958 			get { return PageIndex; }
959 		}
960 
961 		int IDataItemContainer.DataItemIndex {
962 			get { return DataItemIndex; }
963 		}
964 
965 		[MonoTODO ("Make use of it in the code")]
966 		[DefaultValue (true)]
967 		public virtual bool EnableModelValidation {
968 			get;
969 			set;
970 		}
971 
IsBindableType(Type type)972 		public virtual bool IsBindableType (Type type)
973 		{
974 			return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal);
975 		}
976 
CreateDataSourceSelectArguments()977 		protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
978 		{
979 			DataSourceSelectArguments arg = new DataSourceSelectArguments ();
980 			DataSourceView view = GetData ();
981 			if (AllowPaging && view.CanPage) {
982 				arg.StartRowIndex = PageIndex;
983 				if (view.CanRetrieveTotalRowCount) {
984 					arg.RetrieveTotalRowCount = true;
985 					arg.MaximumRows = 1;
986 				} else
987 					arg.MaximumRows = -1;
988 			}
989 			return arg;
990 		}
991 
CreateFieldSet(object dataItem, bool useDataSource)992 		protected virtual ICollection CreateFieldSet (object dataItem, bool useDataSource)
993 		{
994 			bool autoGenerate = AutoGenerateRows;
995 
996 			if (autoGenerate) {
997 				IAutoFieldGenerator fieldGenerator = RowsGenerator;
998 				if (fieldGenerator != null)
999 					return fieldGenerator.GenerateFields (this);
1000 			}
1001 
1002 			ArrayList fields = new ArrayList ();
1003 
1004 			if (AutoGenerateRows) {
1005 				if (useDataSource) {
1006 					if (dataItem != null)
1007 						fields.AddRange (CreateAutoGeneratedRows (dataItem));
1008 				} else {
1009 					if (autoFieldProperties != null) {
1010 						foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1011 							fields.Add (CreateAutoGeneratedRow (props));
1012 					}
1013 				}
1014 			}
1015 
1016 			fields.AddRange (Fields);
1017 
1018 			if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateInsertButton) {
1019 				CommandField field = new CommandField ();
1020 				field.ShowEditButton = AutoGenerateEditButton;
1021 				field.ShowDeleteButton = AutoGenerateDeleteButton;
1022 				field.ShowInsertButton = AutoGenerateInsertButton;
1023 				fields.Add (field);
1024 			}
1025 
1026 			return fields;
1027 		}
1028 
CreateAutoGeneratedRows(object dataItem)1029 		protected virtual ICollection CreateAutoGeneratedRows (object dataItem)
1030 		{
1031 			if (dataItem == null)
1032 				return null;
1033 
1034 			ArrayList list = new ArrayList ();
1035 			autoFieldProperties = CreateAutoFieldProperties (dataItem);
1036 			foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1037 				list.Add (CreateAutoGeneratedRow (props));
1038 			return list;
1039 		}
1040 
CreateAutoGeneratedRow(AutoGeneratedFieldProperties fieldProperties)1041 		protected virtual AutoGeneratedField CreateAutoGeneratedRow (AutoGeneratedFieldProperties fieldProperties)
1042 		{
1043 			return new AutoGeneratedField (fieldProperties);
1044 		}
1045 
CreateAutoFieldProperties(object dataItem)1046 		AutoGeneratedFieldProperties[] CreateAutoFieldProperties (object dataItem)
1047 		{
1048 			if (IsBindableType (dataItem.GetType ())) {
1049 				AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1050 				((IStateManager) field).TrackViewState ();
1051 				field.Name = "Item";
1052 				field.DataField = BoundField.ThisExpression;
1053 				field.Type = dataItem.GetType ();
1054 				return new AutoGeneratedFieldProperties [] { field };
1055 			}
1056 
1057 			PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem, false);
1058 
1059 			if (props != null && props.Count > 0) {
1060 				ArrayList retVal = new ArrayList ();
1061 				foreach (PropertyDescriptor current in props) {
1062 					if (IsBindableType (current.PropertyType)) {
1063 						AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1064 						((IStateManager) field).TrackViewState ();
1065 						field.Name = current.Name;
1066 						field.DataField = current.Name;
1067 						for (int i = 0; i < DataKeyNames.Length; i++) {
1068 							if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
1069 								field.IsReadOnly = true;
1070 								break;
1071 							}
1072 						}
1073 						field.Type = current.PropertyType;
1074 						retVal.Add (field);
1075 					}
1076 				}
1077 				if (retVal.Count > 0)
1078 					return (AutoGeneratedFieldProperties []) retVal.ToArray (typeof (AutoGeneratedFieldProperties));
1079 			}
1080 			throw new HttpException (String.Format ("DetailsView with id '{0}' did not have any properties or attributes from which to generate fields.  Ensure that your data source has content.", ID));
1081 		}
1082 
CreateRow(int rowIndex, DataControlRowType rowType, DataControlRowState rowState)1083 		protected virtual DetailsViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
1084 		{
1085 			DetailsViewRow row;
1086 			if (rowType == DataControlRowType.Pager)
1087 				row = new DetailsViewPagerRow (rowIndex, rowType, rowState);
1088 			else
1089 				row = new DetailsViewRow (rowIndex, rowType, rowState);
1090 			return row;
1091 		}
1092 
RequireBinding()1093 		void RequireBinding ()
1094 		{
1095 			if (Initialized)
1096 				RequiresDataBinding = true;
1097 		}
1098 
CreateTable()1099 		protected virtual Table CreateTable ()
1100 		{
1101 			return new ContainedTable (this);
1102 		}
1103 
CreateControlStyle()1104 		protected override Style CreateControlStyle ()
1105 		{
1106 			TableStyle style = new TableStyle ();
1107 			style.GridLines = GridLines.Both;
1108 			style.CellSpacing = 0;
1109 			return style;
1110 		}
1111 
CreateChildControls(IEnumerable dataSource, bool dataBinding)1112 		protected override int CreateChildControls (IEnumerable dataSource, bool dataBinding)
1113 		{
1114 			PagedDataSource pagedDataSource = new PagedDataSource ();
1115 			pagedDataSource.DataSource = CurrentMode != DetailsViewMode.Insert ? dataSource : null;
1116 			pagedDataSource.AllowPaging = AllowPaging;
1117 			pagedDataSource.PageSize = 1;
1118 			pagedDataSource.CurrentPageIndex = PageIndex;
1119 
1120 			if (dataBinding && CurrentMode != DetailsViewMode.Insert) {
1121 				DataSourceView view = GetData ();
1122 				if (view != null && view.CanPage) {
1123 					pagedDataSource.AllowServerPaging = true;
1124 					if (SelectArguments.RetrieveTotalRowCount)
1125 						pagedDataSource.VirtualCount = SelectArguments.TotalRowCount;
1126 				}
1127 			}
1128 
1129 			bool showPager = AllowPaging && (pagedDataSource.PageCount > 1);
1130 
1131 			Controls.Clear ();
1132 			table = CreateTable ();
1133 			Controls.Add (table);
1134 			headerRow = null;
1135 			footerRow = null;
1136 			topPagerRow = null;
1137 			bottomPagerRow = null;
1138 			ArrayList list = new ArrayList ();
1139 
1140 			// Gets the current data item
1141 
1142 			if (AllowPaging) {
1143 				PageCount = pagedDataSource.DataSourceCount;
1144 				if (PageIndex >= PageCount && PageCount > 0)
1145 					pageIndex = pagedDataSource.CurrentPageIndex = PageCount - 1;
1146 				if (pagedDataSource.DataSource != null) {
1147 					IEnumerator e = pagedDataSource.GetEnumerator ();
1148 					if (e.MoveNext ())
1149 						dataItem = e.Current;
1150 				}
1151 			} else {
1152 				int page = 0;
1153 				object lastItem = null;
1154 				if (pagedDataSource.DataSource != null) {
1155 					IEnumerator e = pagedDataSource.GetEnumerator ();
1156 					for (; e.MoveNext (); page++) {
1157 						lastItem = e.Current;
1158 						if (page == PageIndex)
1159 							dataItem = e.Current;
1160 					}
1161 				}
1162 				PageCount = page;
1163 				if (PageIndex >= PageCount && PageCount > 0) {
1164 					pageIndex = PageCount - 1;
1165 					dataItem = lastItem;
1166 				}
1167 			}
1168 
1169 			if (PageCount == 0 && CurrentMode != DetailsViewMode.Insert) {
1170 				DetailsViewRow row = CreateEmptyRow ();
1171 				if (row != null) {
1172 					table.Rows.Add (row);
1173 					list.Add (row);
1174 				}
1175 			} else {
1176 				// Creates the set of fields to show
1177 
1178 				ICollection fieldCollection = CreateFieldSet (dataItem, dataBinding && dataItem != null);
1179 				DataControlField [] fields = new DataControlField [fieldCollection.Count];
1180 				fieldCollection.CopyTo (fields, 0);
1181 
1182 				foreach (DataControlField field in fields) {
1183 					field.Initialize (false, this);
1184 					if (EnablePagingCallbacks)
1185 						field.ValidateSupportsCallback ();
1186 				}
1187 
1188 				// Main table creation
1189 
1190 				headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
1191 				DataControlFieldCell headerCell = new DataControlFieldCell (null);
1192 				headerCell.ColumnSpan = 2;
1193 				if (headerTemplate != null)
1194 					headerTemplate.InstantiateIn (headerCell);
1195 				else if (!String.IsNullOrEmpty (HeaderText))
1196 					headerCell.Text = HeaderText;
1197 				else
1198 					headerRow.Visible = false;
1199 				headerRow.Cells.Add (headerCell);
1200 				table.Rows.Add (headerRow);
1201 
1202 				if (showPager && PagerSettings.Position == PagerPosition.Top ||
1203 						PagerSettings.Position == PagerPosition.TopAndBottom) {
1204 					topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1205 					InitializePager (topPagerRow, pagedDataSource);
1206 					table.Rows.Add (topPagerRow);
1207 				}
1208 
1209 				foreach (DataControlField field in fields) {
1210 					DataControlRowState rstate = GetRowState (list.Count);
1211 					DetailsViewRow row = CreateRow (PageIndex, DataControlRowType.DataRow, rstate);
1212 					InitializeRow (row, field);
1213 					table.Rows.Add (row);
1214 					list.Add (row);
1215 				}
1216 
1217 				footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
1218 				DataControlFieldCell footerCell = new DataControlFieldCell (null);
1219 				footerCell.ColumnSpan = 2;
1220 				if (footerTemplate != null)
1221 					footerTemplate.InstantiateIn (footerCell);
1222 				else if (!String.IsNullOrEmpty (FooterText))
1223 					footerCell.Text = FooterText;
1224 				else
1225 					footerRow.Visible = false;
1226 				footerRow.Cells.Add (footerCell);
1227 				table.Rows.Add (footerRow);
1228 
1229 				if (showPager && PagerSettings.Position == PagerPosition.Bottom ||
1230 						PagerSettings.Position == PagerPosition.TopAndBottom) {
1231 					bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1232 					InitializePager (bottomPagerRow, pagedDataSource);
1233 					table.Rows.Add (bottomPagerRow);
1234 				}
1235 			}
1236 
1237 			rows = new DetailsViewRowCollection (list);
1238 
1239 			if (dataBinding)
1240 				DataBind (false);
1241 
1242 			OnItemCreated (EventArgs.Empty);
1243 
1244 			return PageCount;
1245 		}
1246 
EnsureDataBound()1247 		protected override void EnsureDataBound ()
1248 		{
1249 			if (CurrentMode == DetailsViewMode.Insert) {
1250 				if (RequiresDataBinding) {
1251 					OnDataBinding (EventArgs.Empty);
1252 					RequiresDataBinding = false;
1253 					InternalPerformDataBinding (null);
1254 					MarkAsDataBound ();
1255 					OnDataBound (EventArgs.Empty);
1256 				}
1257 			} else
1258 				base.EnsureDataBound ();
1259 		}
1260 
GetRowState(int index)1261 		DataControlRowState GetRowState (int index)
1262 		{
1263 			DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
1264 			if (CurrentMode == DetailsViewMode.Edit)
1265 				rstate |= DataControlRowState.Edit;
1266 			else if (CurrentMode == DetailsViewMode.Insert)
1267 				rstate |= DataControlRowState.Insert;
1268 			return rstate;
1269 		}
1270 
InitializePager(DetailsViewRow row, PagedDataSource pagedDataSource)1271 		protected virtual void InitializePager (DetailsViewRow row, PagedDataSource pagedDataSource)
1272 		{
1273 			TableCell cell = new TableCell ();
1274 			cell.ColumnSpan = 2;
1275 
1276 			if (pagerTemplate != null)
1277 				pagerTemplate.InstantiateIn (cell);
1278 			else
1279 				cell.Controls.Add (PagerSettings.CreatePagerControl (pagedDataSource.CurrentPageIndex, pagedDataSource.PageCount));
1280 
1281 			row.Cells.Add (cell);
1282 		}
1283 
CreateEmptyRow()1284 		DetailsViewRow CreateEmptyRow ()
1285 		{
1286 			TableCell cell = new TableCell ();
1287 
1288 			if (emptyDataTemplate != null)
1289 				emptyDataTemplate.InstantiateIn (cell);
1290 			else if (!String.IsNullOrEmpty (EmptyDataText))
1291 				cell.Text = EmptyDataText;
1292 			else
1293 				return null;
1294 
1295 			DetailsViewRow row = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
1296 			row.Cells.Add (cell);
1297 			return row;
1298 		}
1299 
InitializeRow(DetailsViewRow row, DataControlField field)1300 		protected virtual void InitializeRow (DetailsViewRow row, DataControlField field)
1301 		{
1302 			if (!field.Visible) {
1303 				row.Visible = false;
1304 				return;
1305 			}
1306 
1307 			row.ContainingField = field;
1308 			DataControlFieldCell cell;
1309 
1310 			if (field.ShowHeader) {
1311 				cell = new DataControlFieldCell (field);
1312 				row.Cells.Add (cell);
1313 				field.InitializeCell (cell, DataControlCellType.Header, row.RowState, row.RowIndex);
1314 			}
1315 
1316 			cell = new DataControlFieldCell (field);
1317 			if (!field.ShowHeader)
1318 				cell.ColumnSpan = 2;
1319 			row.Cells.Add (cell);
1320 			field.InitializeCell (cell, DataControlCellType.DataCell, row.RowState, row.RowIndex);
1321 
1322 			if (CurrentMode == DetailsViewMode.Insert && !field.InsertVisible)
1323 				row.Visible = false;
1324 		}
1325 
FillRowDataKey(object dataItem)1326 		void FillRowDataKey (object dataItem)
1327 		{
1328 			KeyTable.Clear ();
1329 
1330 			if (cachedKeyProperties == null) {
1331 				PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
1332 				cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
1333 				for (int n=0; n<DataKeyNames.Length; n++) {
1334 					PropertyDescriptor p = props.Find (DataKeyNames [n], true);
1335 					if (p == null)
1336 						throw new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
1337 					cachedKeyProperties [n] = p;
1338 				}
1339 			}
1340 
1341 			foreach (PropertyDescriptor p in cachedKeyProperties)
1342 				KeyTable [p.Name] = p.GetValue (dataItem);
1343 		}
1344 
GetRowValues(bool includeReadOnlyFields, bool includePrimaryKey)1345 		IOrderedDictionary GetRowValues (bool includeReadOnlyFields, bool includePrimaryKey)
1346 		{
1347 			OrderedDictionary dic = new OrderedDictionary ();
1348 			ExtractRowValues (dic, includeReadOnlyFields, includePrimaryKey);
1349 			return dic;
1350 		}
1351 
ExtractRowValues(IOrderedDictionary fieldValues, bool includeReadOnlyFields, bool includeKeys)1352 		protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeReadOnlyFields, bool includeKeys)
1353 		{
1354 			foreach (DetailsViewRow row in Rows) {
1355 				if (row.Cells.Count < 1)
1356 					continue;
1357 				DataControlFieldCell c = row.Cells[row.Cells.Count-1] as DataControlFieldCell;
1358 				if (c != null)
1359 					c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
1360 			}
1361 			if (!includeKeys && DataKeyNames != null)
1362 				foreach (string key in DataKeyNames)
1363 					fieldValues.Remove (key);
1364 		}
1365 
1366 		protected override HtmlTextWriterTag TagKey {
1367 			get {
1368 				if (EnablePagingCallbacks)
1369 					return HtmlTextWriterTag.Div;
1370 				else
1371 					return HtmlTextWriterTag.Table;
1372 			}
1373 		}
1374 
DataBind()1375 		public sealed override void DataBind ()
1376 		{
1377 			cachedKeyProperties = null;
1378 			base.DataBind ();
1379 
1380 			if (dataItem != null) {
1381 				if (CurrentMode == DetailsViewMode.Edit)
1382 					oldEditValues = new DataKey (GetRowValues (false, true));
1383 				FillRowDataKey (dataItem);
1384 				key = new DataKey (KeyTable);
1385 			}
1386 		}
1387 
PerformDataBinding(IEnumerable data)1388 		protected internal override void PerformDataBinding (IEnumerable data)
1389 		{
1390 			base.PerformDataBinding (data);
1391 		}
1392 
PrepareControlHierarchy()1393 		protected internal virtual void PrepareControlHierarchy ()
1394 		{
1395 			if (table == null)
1396 				return;
1397 
1398 			table.Caption = Caption;
1399 			table.CaptionAlign = CaptionAlign;
1400 
1401 			foreach (DetailsViewRow row in table.Rows) {
1402 				switch (row.RowType) {
1403 					case DataControlRowType.Header:
1404 						if (headerStyle != null && !headerStyle.IsEmpty)
1405 							row.ControlStyle.CopyFrom (headerStyle);
1406 						break;
1407 					case DataControlRowType.Footer:
1408 						if (footerStyle != null && !footerStyle.IsEmpty)
1409 							row.ControlStyle.CopyFrom (footerStyle);
1410 						break;
1411 					case DataControlRowType.Pager:
1412 						if (pagerStyle != null && !pagerStyle.IsEmpty)
1413 							row.ControlStyle.CopyFrom (pagerStyle);
1414 						break;
1415 					case DataControlRowType.EmptyDataRow:
1416 						if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1417 							row.ControlStyle.CopyFrom (emptyDataRowStyle);
1418 						break;
1419 					case DataControlRowType.DataRow:
1420 						if (rowStyle != null && !rowStyle.IsEmpty)
1421 							row.ControlStyle.CopyFrom (rowStyle);
1422 						if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
1423 							row.ControlStyle.CopyFrom (alternatingRowStyle);
1424 						break;
1425 					default:
1426 						break;
1427 				}
1428 
1429 				if (row.ContainingField is CommandField) {
1430 					if (commandRowStyle != null && !commandRowStyle.IsEmpty)
1431 						row.ControlStyle.CopyFrom (commandRowStyle);
1432 				} else {
1433 					if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1434 						row.ControlStyle.CopyFrom (editRowStyle);
1435 					if ((row.RowState & DataControlRowState.Insert) != 0) {
1436 						if (insertRowStyle != null && !insertRowStyle.IsEmpty)
1437 							row.ControlStyle.CopyFrom (insertRowStyle);
1438 						else if (editRowStyle != null && !editRowStyle.IsEmpty)
1439 							row.ControlStyle.CopyFrom (editRowStyle);
1440 					}
1441 				}
1442 
1443 				for (int n = 0; n < row.Cells.Count; n++) {
1444 					DataControlFieldCell fcell = row.Cells [n] as DataControlFieldCell;
1445 					if (fcell != null && fcell.ContainingField != null) {
1446 						DataControlField field = fcell.ContainingField;
1447 						if (n == 0 && field.ShowHeader) {
1448 							if (fieldHeaderStyle != null && !fieldHeaderStyle.IsEmpty)
1449 								fcell.ControlStyle.CopyFrom (fieldHeaderStyle);
1450 							if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
1451 								fcell.ControlStyle.CopyFrom (field.HeaderStyle);
1452 						} else {
1453 							if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty) {
1454 								foreach (Control c in fcell.Controls) {
1455 									WebControl wc = c as WebControl;
1456 									if (wc != null)
1457 										wc.ControlStyle.MergeWith (field.ControlStyle);
1458 								}
1459 							}
1460 
1461 							if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
1462 								fcell.ControlStyle.CopyFrom (field.ItemStyle);
1463 						}
1464 					}
1465 				}
1466 			}
1467 		}
1468 
OnInit(EventArgs e)1469 		protected internal override void OnInit (EventArgs e)
1470 		{
1471 			Page page = Page;
1472 			if (page != null)
1473 				page.RegisterRequiresControlState (this);
1474 			base.OnInit (e);
1475 		}
1476 
OnFieldsChanged(object sender, EventArgs args)1477 		void OnFieldsChanged (object sender, EventArgs args)
1478 		{
1479 			RequireBinding ();
1480 		}
1481 
OnDataSourceViewChanged(object sender, EventArgs e)1482 		protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1483 		{
1484 			base.OnDataSourceViewChanged (sender, e);
1485 			RequireBinding ();
1486 		}
1487 
OnBubbleEvent(object source, EventArgs e)1488 		protected override bool OnBubbleEvent (object source, EventArgs e)
1489 		{
1490 			DetailsViewCommandEventArgs args = e as DetailsViewCommandEventArgs;
1491 			if (args != null) {
1492 				bool causesValidation = false;
1493 				IButtonControl button = args.CommandSource as IButtonControl;
1494 				if (button != null && button.CausesValidation) {
1495 					Page.Validate (button.ValidationGroup);
1496 					causesValidation = true;
1497 				}
1498 				ProcessCommand (args, causesValidation);
1499 				return true;
1500 			}
1501 			return base.OnBubbleEvent (source, e);
1502 		}
1503 
ProcessCommand(DetailsViewCommandEventArgs args, bool causesValidation)1504 		void ProcessCommand (DetailsViewCommandEventArgs args, bool causesValidation) {
1505 			OnItemCommand (args);
1506 			ProcessEvent (args.CommandName, args.CommandArgument as string, causesValidation);
1507 		}
1508 
IPostBackEventHandler.RaisePostBackEvent(string eventArgument)1509 		void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1510 		{
1511 			RaisePostBackEvent (eventArgument);
1512 		}
1513 
1514 		// TODO: This is prolly obsolete
RaisePostBackEvent(string eventArgument)1515 		protected virtual void RaisePostBackEvent (string eventArgument)
1516 		{
1517 			ValidateEvent (UniqueID, eventArgument);
1518 			int i = eventArgument.IndexOf ('$');
1519 			CommandEventArgs arg;
1520 			if (i != -1)
1521 				arg = new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
1522 			else
1523 				arg = new CommandEventArgs (eventArgument, null);
1524 			ProcessCommand (new DetailsViewCommandEventArgs (this, arg), false);
1525 		}
1526 
ProcessEvent(string eventName, string param, bool causesValidation)1527 		void ProcessEvent (string eventName, string param, bool causesValidation)
1528 		{
1529 			switch (eventName) {
1530 				case DataControlCommands.PageCommandName:
1531 					int newIndex = -1;
1532 					switch (param) {
1533 						case DataControlCommands.FirstPageCommandArgument:
1534 							newIndex = 0;
1535 							break;
1536 						case DataControlCommands.LastPageCommandArgument:
1537 							newIndex = PageCount - 1;
1538 							break;
1539 						case DataControlCommands.NextPageCommandArgument:
1540 							newIndex = PageIndex + 1;
1541 							break;
1542 						case DataControlCommands.PreviousPageCommandArgument:
1543 							newIndex = PageIndex - 1;
1544 							break;
1545 						default:
1546 							int paramIndex = 0;
1547 							int.TryParse (param, out paramIndex);
1548 							newIndex = paramIndex - 1;
1549 							break;
1550 					}
1551 					SetPageIndex (newIndex);
1552 					break;
1553 
1554 				case DataControlCommands.FirstPageCommandArgument:
1555 					SetPageIndex (0);
1556 					break;
1557 
1558 				case DataControlCommands.LastPageCommandArgument:
1559 					SetPageIndex (PageCount - 1);
1560 					break;
1561 
1562 				case DataControlCommands.NextPageCommandArgument:
1563 					if (PageIndex < PageCount - 1)
1564 						SetPageIndex (PageIndex + 1);
1565 					break;
1566 
1567 				case DataControlCommands.PreviousPageCommandArgument:
1568 					if (PageIndex > 0)
1569 						SetPageIndex (PageIndex - 1);
1570 					break;
1571 
1572 				case DataControlCommands.EditCommandName:
1573 					ProcessChangeMode (DetailsViewMode.Edit);
1574 					break;
1575 
1576 				case DataControlCommands.NewCommandName:
1577 					ProcessChangeMode (DetailsViewMode.Insert);
1578 					break;
1579 
1580 				case DataControlCommands.UpdateCommandName:
1581 					UpdateItem (param, causesValidation);
1582 					break;
1583 
1584 				case DataControlCommands.CancelCommandName:
1585 					CancelEdit ();
1586 					break;
1587 
1588 				case DataControlCommands.DeleteCommandName:
1589 					DeleteItem ();
1590 					break;
1591 
1592 				case DataControlCommands.InsertCommandName:
1593 					InsertItem (causesValidation);
1594 					break;
1595 			}
1596 		}
1597 		public
SetPageIndex(int index)1598 		void SetPageIndex (int index)
1599 		{
1600 			DetailsViewPageEventArgs args = new DetailsViewPageEventArgs (index);
1601 			OnPageIndexChanging (args);
1602 
1603 			if (args.Cancel || !IsBoundUsingDataSourceID)
1604 				return;
1605 
1606 			if (args.NewPageIndex < 0 || args.NewPageIndex >= PageCount)
1607 				return;
1608 			EndRowEdit (false);
1609 			PageIndex = args.NewPageIndex;
1610 			OnPageIndexChanged (EventArgs.Empty);
1611 		}
1612 
ChangeMode(DetailsViewMode newMode)1613 		public void ChangeMode (DetailsViewMode newMode)
1614 		{
1615 			CurrentMode = newMode;
1616 			RequireBinding ();
1617 		}
1618 
ProcessChangeMode(DetailsViewMode newMode)1619 		void ProcessChangeMode (DetailsViewMode newMode)
1620 		{
1621 			DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (newMode, false);
1622 			OnModeChanging (args);
1623 
1624 			if (args.Cancel || !IsBoundUsingDataSourceID)
1625 				return;
1626 
1627 			ChangeMode (args.NewMode);
1628 
1629 			OnModeChanged (EventArgs.Empty);
1630 		}
1631 
CancelEdit()1632 		void CancelEdit ()
1633 		{
1634 			DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (DetailsViewMode.ReadOnly, true);
1635 			OnModeChanging (args);
1636 
1637 			if (args.Cancel || !IsBoundUsingDataSourceID)
1638 				return;
1639 
1640 			EndRowEdit ();
1641 		}
1642 
UpdateItem(bool causesValidation)1643 		public virtual void UpdateItem (bool causesValidation)
1644 		{
1645 			UpdateItem (null, causesValidation);
1646 		}
1647 
UpdateItem(string param, bool causesValidation)1648 		void UpdateItem (string param, bool causesValidation)
1649 		{
1650 			if (causesValidation && Page != null && !Page.IsValid)
1651 				return;
1652 
1653 			if (CurrentMode != DetailsViewMode.Edit)
1654 				throw new HttpException ();
1655 
1656 			currentEditOldValues = OldEditValues.Values;
1657 
1658 			currentEditRowKeys = DataKey.Values;
1659 			currentEditNewValues = GetRowValues (false, false);
1660 
1661 			DetailsViewUpdateEventArgs args = new DetailsViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1662 			OnItemUpdating (args);
1663 
1664 			if (args.Cancel || !IsBoundUsingDataSourceID)
1665 				return;
1666 
1667 			DataSourceView view = GetData ();
1668 			if (view == null)
1669 				throw new HttpException ("The DataSourceView associated to data bound control was null");
1670 			view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1671 		}
1672 
UpdateCallback(int recordsAffected, Exception exception)1673 		bool UpdateCallback (int recordsAffected, Exception exception)
1674 		{
1675 			DetailsViewUpdatedEventArgs dargs = new DetailsViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1676 			OnItemUpdated (dargs);
1677 
1678 			if (!dargs.KeepInEditMode)
1679 				EndRowEdit ();
1680 
1681 			return dargs.ExceptionHandled;
1682 		}
1683 
InsertItem(bool causesValidation)1684 		public virtual void InsertItem (bool causesValidation)
1685 		{
1686 			InsertItem (null, causesValidation);
1687 		}
1688 
InsertItem(string param, bool causesValidation)1689 		void InsertItem (string param, bool causesValidation)
1690 		{
1691 			if (causesValidation && Page != null && !Page.IsValid)
1692 				return;
1693 
1694 			if (CurrentMode != DetailsViewMode.Insert)
1695 				throw new HttpException ();
1696 
1697 			currentEditNewValues = GetRowValues (false, true);
1698 			DetailsViewInsertEventArgs args = new DetailsViewInsertEventArgs (param, currentEditNewValues);
1699 			OnItemInserting (args);
1700 
1701 			if (args.Cancel || !IsBoundUsingDataSourceID)
1702 				return;
1703 
1704 			DataSourceView view = GetData ();
1705 			if (view == null)
1706 				throw new HttpException ("The DataSourceView associated to data bound control was null");
1707 			view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
1708 		}
1709 
InsertCallback(int recordsAffected, Exception exception)1710 		bool InsertCallback (int recordsAffected, Exception exception)
1711 		{
1712 			DetailsViewInsertedEventArgs dargs = new DetailsViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
1713 			OnItemInserted (dargs);
1714 
1715 			if (!dargs.KeepInInsertMode)
1716 				EndRowEdit ();
1717 
1718 			return dargs.ExceptionHandled;
1719 		}
1720 
DeleteItem()1721 		public virtual void DeleteItem ()
1722 		{
1723 			currentEditRowKeys = DataKey.Values;
1724 			currentEditNewValues = GetRowValues (true, false);
1725 
1726 			DetailsViewDeleteEventArgs args = new DetailsViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
1727 			OnItemDeleting (args);
1728 
1729 			if (args.Cancel || !IsBoundUsingDataSourceID)
1730 				return;
1731 
1732 			DataSourceView view = GetData ();
1733 			if (view != null)
1734 				view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1735 			else {
1736 				DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1737 				OnItemDeleted (dargs);
1738 			}
1739 			if (PageIndex > 0 && PageIndex == PageCount - 1)
1740 				PageIndex --;
1741 			RequireBinding ();
1742 		}
1743 
DeleteCallback(int recordsAffected, Exception exception)1744 		bool DeleteCallback (int recordsAffected, Exception exception)
1745 		{
1746 			DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1747 			OnItemDeleted (dargs);
1748 			return dargs.ExceptionHandled;
1749 		}
1750 
EndRowEdit()1751 		void EndRowEdit ()
1752 		{
1753 			EndRowEdit (true);
1754 		}
1755 
EndRowEdit(bool switchToDefaultMode)1756 		void EndRowEdit (bool switchToDefaultMode)
1757 		{
1758 			if (switchToDefaultMode)
1759 				ChangeMode (DefaultMode);
1760 			oldEditValues = new DataKey (new OrderedDictionary ());
1761 			currentEditRowKeys = null;
1762 			currentEditOldValues = null;
1763 			currentEditNewValues = null;
1764 			RequireBinding ();
1765 		}
1766 
LoadControlState(object savedState)1767 		protected internal override void LoadControlState (object savedState)
1768 		{
1769 			if (savedState == null)
1770 				return;
1771 			object[] state = (object[]) savedState;
1772 			base.LoadControlState (state[0]);
1773 			pageIndex = (int) state[1];
1774 			pageCount = (int) state[2];
1775 			CurrentMode = (DetailsViewMode) state[3];
1776 			dataKeyNames = (string[]) state[4];
1777 			defaultMode = (DetailsViewMode) state[5];
1778 			if (state [6] != null)
1779 				((IStateManager) DataKey).LoadViewState (state [6]);
1780 			if (state [7] != null)
1781 				((IStateManager) OldEditValues).LoadViewState (state [7]);
1782 		}
1783 
SaveControlState()1784 		protected internal override object SaveControlState ()
1785 		{
1786 			object bstate = base.SaveControlState ();
1787 			return new object[] {
1788 				bstate,
1789 				pageIndex,
1790 				pageCount,
1791 				CurrentMode,
1792 				dataKeyNames,
1793 				defaultMode,
1794 				(key == null ? null : ((IStateManager)key).SaveViewState()),
1795 				(oldEditValues == null ? null : ((IStateManager) oldEditValues).SaveViewState ())
1796 			};
1797 		}
1798 
TrackViewState()1799 		protected override void TrackViewState()
1800 		{
1801 			base.TrackViewState();
1802 			if (columns != null)
1803 				((IStateManager)columns).TrackViewState();
1804 			if (pagerSettings != null)
1805 				((IStateManager)pagerSettings).TrackViewState();
1806 			if (alternatingRowStyle != null)
1807 				((IStateManager)alternatingRowStyle).TrackViewState();
1808 			if (footerStyle != null)
1809 				((IStateManager)footerStyle).TrackViewState();
1810 			if (headerStyle != null)
1811 				((IStateManager)headerStyle).TrackViewState();
1812 			if (pagerStyle != null)
1813 				((IStateManager)pagerStyle).TrackViewState();
1814 			if (rowStyle != null)
1815 				((IStateManager)rowStyle).TrackViewState();
1816 			if (editRowStyle != null)
1817 				((IStateManager)editRowStyle).TrackViewState();
1818 			if (insertRowStyle != null)
1819 				((IStateManager)insertRowStyle).TrackViewState();
1820 			if (emptyDataRowStyle != null)
1821 				((IStateManager)emptyDataRowStyle).TrackViewState();
1822 			if (key != null)
1823 				((IStateManager)key).TrackViewState();
1824 			if (autoFieldProperties != null) {
1825 				foreach (IStateManager sm in autoFieldProperties)
1826 					sm.TrackViewState ();
1827 			}
1828 			if (ControlStyleCreated)
1829 				ControlStyle.TrackViewState ();
1830 		}
1831 
SaveViewState()1832 		protected override object SaveViewState()
1833 		{
1834 			object[] states = new object [13];
1835 			states[0] = base.SaveViewState();
1836 			states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState());
1837 			states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1838 			states[3] = (alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState());
1839 			states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1840 			states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1841 			states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1842 			states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1843 			states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
1844 			states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1845 			states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1846 
1847 			if (autoFieldProperties != null) {
1848 				object[] data = new object [autoFieldProperties.Length];
1849 				bool allNull = true;
1850 				for (int n=0; n<data.Length; n++) {
1851 					data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
1852 					if (data [n] != null) allNull = false;
1853 				}
1854 				if (!allNull) states [11] = data;
1855 			}
1856 			if (ControlStyleCreated)
1857 				states [12] = ControlStyle.SaveViewState ();
1858 
1859 			for (int i = states.Length - 1; i >= 0; i--) {
1860 				if (states [i] != null)
1861 					return states;
1862 			}
1863 
1864 			return null;
1865 		}
1866 
LoadViewState(object savedState)1867 		protected override void LoadViewState (object savedState)
1868 		{
1869 			if (savedState == null) {
1870 				base.LoadViewState (null);
1871 				return;
1872 			}
1873 
1874 			object [] states = (object []) savedState;
1875 
1876 			if (states[11] != null) {
1877 				object[] data = (object[]) states [11];
1878 				autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
1879 				for (int n=0; n<data.Length; n++) {
1880 					IStateManager p = new AutoGeneratedFieldProperties ();
1881 					p.TrackViewState ();
1882 					p.LoadViewState (data [n]);
1883 					autoFieldProperties [n] = (AutoGeneratedFieldProperties) p;
1884 				}
1885 			}
1886 
1887 			base.LoadViewState (states[0]);
1888 
1889 			if (states[1] != null) ((IStateManager)Fields).LoadViewState (states[1]);
1890 			if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1891 			if (states[3] != null) ((IStateManager)AlternatingRowStyle).LoadViewState (states[3]);
1892 			if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1893 			if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1894 			if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1895 			if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1896 			if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
1897 			if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1898 			if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
1899 			if (states [12] != null)
1900 				ControlStyle.LoadViewState (states [12]);
1901 		}
1902 
ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)1903 		void ICallbackEventHandler.RaiseCallbackEvent (string eventArgument)
1904 		{
1905 			RaiseCallbackEvent (eventArgument);
1906 		}
1907 
RaiseCallbackEvent(string eventArgument)1908 		protected virtual void RaiseCallbackEvent (string eventArgument)
1909 		{
1910 			string[] clientData = eventArgument.Split ('|');
1911 			PageIndex = int.Parse (clientData[0]);
1912 
1913 			RaisePostBackEvent (clientData[1]);
1914 			DataBind ();
1915 		}
1916 
ICallbackEventHandler.GetCallbackResult()1917 		string ICallbackEventHandler.GetCallbackResult ()
1918 		{
1919 			return GetCallbackResult ();
1920 		}
1921 
GetCallbackResult()1922 		protected virtual string GetCallbackResult ()
1923 		{
1924 			PrepareControlHierarchy ();
1925 
1926 			StringWriter sw = new StringWriter ();
1927 			sw.Write (PageIndex.ToString () + '|');
1928 
1929 			HtmlTextWriter writer = new HtmlTextWriter (sw);
1930 			RenderGrid (writer);
1931 			return sw.ToString ();
1932 		}
1933 
GetCallbackScript(IButtonControl buttonControl, string argument)1934 		protected virtual string GetCallbackScript (IButtonControl buttonControl, string argument)
1935 		{
1936 			if (EnablePagingCallbacks) {
1937 				Page page = Page;
1938 				if (page != null)
1939 					page.ClientScript.RegisterForEventValidation (UniqueID, argument);
1940 				return "javascript:DetailsView_ClientEvent (\"" + ClientID + "\",\"" + buttonControl.CommandName + "$" + buttonControl.CommandArgument + "\"); return false;";
1941 			} else
1942 				return null;
1943 		}
1944 
ICallbackContainer.GetCallbackScript(IButtonControl control, string argument)1945 		string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
1946 		{
1947 			return GetCallbackScript (control, argument);
1948 		}
1949 
OnPagePreLoad(object sender, EventArgs e)1950 		protected override void OnPagePreLoad (object sender, EventArgs e)
1951 		{
1952 			base.OnPagePreLoad (sender, e);
1953 
1954 			if (Page.IsPostBack && EnablePagingCallbacks) {
1955 				int page;
1956 				if (int.TryParse (Page.Request.Form [ClientID + "_Page"], out page))
1957 					PageIndex = page;
1958 			}
1959 		}
1960 
1961 		const string onPreRenderScript = @"var {0} = new Object ();
1962 {0}.pageIndex = {1};
1963 {0}.uid = {2};
1964 {0}.form = {3};
1965 ";
OnPreRender(EventArgs e)1966 		protected internal override void OnPreRender (EventArgs e)
1967 		{
1968 			base.OnPreRender (e);
1969 
1970 			Page page = Page;
1971 			if (EnablePagingCallbacks && page != null) {
1972 				ClientScriptManager scriptManager = page.ClientScript;
1973 				if (!scriptManager.IsClientScriptIncludeRegistered (typeof(DetailsView), "DetailsView.js")) {
1974 					string url = scriptManager.GetWebResourceUrl (typeof(DetailsView), "DetailsView.js");
1975 					scriptManager.RegisterClientScriptInclude (typeof(DetailsView), "DetailsView.js", url);
1976 				}
1977 				scriptManager.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
1978 
1979 				string cgrid = ClientID + "_data";
1980 				string script = String.Format (onPreRenderScript,
1981 							       cgrid,
1982 							       ClientScriptManager.GetScriptLiteral (PageIndex),
1983 							       ClientScriptManager.GetScriptLiteral (UniqueID),
1984 							       page.theForm);
1985 
1986 				scriptManager.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
1987 
1988 				// Make sure the basic script infrastructure is rendered
1989 				scriptManager.GetCallbackEventReference (this, "null", String.Empty, "null");
1990 				scriptManager.GetPostBackClientHyperlink (this, String.Empty, true);
1991 			}
1992 		}
1993 
Render(HtmlTextWriter writer)1994 		protected internal override void Render (HtmlTextWriter writer)
1995 		{
1996 			PrepareControlHierarchy ();
1997 
1998 			if (EnablePagingCallbacks)
1999 				writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
2000 			writer.RenderBeginTag (HtmlTextWriterTag.Div);
2001 
2002 			RenderGrid (writer);
2003 
2004 			writer.RenderEndTag ();
2005 		}
2006 
RenderGrid(HtmlTextWriter writer)2007 		void RenderGrid (HtmlTextWriter writer)
2008 		{
2009 			if (table == null)
2010 				return;
2011 
2012 			table.Render (writer);
2013 		}
2014 
IPostBackContainer.GetPostBackOptions(IButtonControl control)2015 		PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
2016 		{
2017 			if (control == null)
2018 				throw new ArgumentNullException ("control");
2019 
2020 			if (control.CausesValidation)
2021 				throw new InvalidOperationException ("A button that causes validation in DetailsView '" + ID + "' is attempting to use the container GridView as the post back target.  The button should either turn off validation or use itself as the post back container.");
2022 
2023 			PostBackOptions options = new PostBackOptions (this);
2024 			options.Argument = control.CommandName + "$" + control.CommandArgument;
2025 			options.RequiresJavaScriptProtocol = true;
2026 
2027 			return options;
2028 		}
2029 	}
2030 }
2031