1 //
2 // System.Web.UI.WebControls.GridView.cs
3 //
4 // Authors:
5 //	Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // Copyright (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.Generic;
32 using System.Collections.Specialized;
33 using System.ComponentModel;
34 using System.Web.UI;
35 using System.Security.Permissions;
36 using System.Text;
37 using System.IO;
38 using System.Reflection;
39 
40 namespace System.Web.UI.WebControls
41 {
42 	[SupportsEventValidation]
43 	[DesignerAttribute ("System.Web.UI.Design.WebControls.GridViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44 	[ControlValuePropertyAttribute ("SelectedValue")]
45 	[DefaultEventAttribute ("SelectedIndexChanged")]
46 	[DataKeyProperty ("DataKey")]
47 	[AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48 	[AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49 	public class GridView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IPostBackEventHandler, IPostBackContainer, IPersistedSelector
50 		, IDataKeysControl, IDataBoundListControl, IDataBoundControl, IFieldControl
51 	{
52 		Table table;
53 		GridViewRowCollection rows;
54 		GridViewRow bottomPagerRow;
55 		GridViewRow topPagerRow;
56 
57 		IOrderedDictionary currentEditRowKeys;
58 		IOrderedDictionary currentEditNewValues;
59 		IOrderedDictionary currentEditOldValues;
60 
61 		ITemplate pagerTemplate;
62 		ITemplate emptyDataTemplate;
63 
64 		PropertyDescriptor[] cachedKeyProperties;
65 		PropertyDescriptor[] cachedSuffixKeyProperties;
66 		// View state
67 		DataControlFieldCollection columns;
68 		PagerSettings pagerSettings;
69 
70 		TableItemStyle alternatingRowStyle;
71 		TableItemStyle editRowStyle;
72 		TableItemStyle emptyDataRowStyle;
73 		TableItemStyle footerStyle;
74 		TableItemStyle headerStyle;
75 		TableItemStyle pagerStyle;
76 		TableItemStyle rowStyle;
77 		TableItemStyle selectedRowStyle;
78 		TableItemStyle sortedAscendingCellStyle;
79 		TableItemStyle sortedAscendingHeaderStyle;
80 		TableItemStyle sortedDescendingCellStyle;
81 		TableItemStyle sortedDescendingHeaderStyle;
82 
83 		List <DataKey> _dataKeySuffixList;
84 		DataKeyArray rowSuffixKeys;
85 		List <DataKey> _dataKeyList;
86 		DataKeyArray keys;
87 		DataKey oldEditValues;
88 		AutoGeneratedFieldProperties[] autoFieldProperties;
89 		string [] dataKeyNames = null;
90 		readonly string[] emptyKeys = new string[0];
91 		IEnumerator _dataEnumerator;
92 
93 		static readonly object PageIndexChangedEvent = new object();
94 		static readonly object PageIndexChangingEvent = new object();
95 		static readonly object RowCancelingEditEvent = new object();
96 		static readonly object RowCommandEvent = new object();
97 		static readonly object RowCreatedEvent = new object();
98 		static readonly object RowDataBoundEvent = new object();
99 		static readonly object RowDeletedEvent = new object();
100 		static readonly object RowDeletingEvent = new object();
101 		static readonly object RowEditingEvent = new object();
102 		static readonly object RowUpdatedEvent = new object();
103 		static readonly object RowUpdatingEvent = new object();
104 		static readonly object SelectedIndexChangedEvent = new object();
105 		static readonly object SelectedIndexChangingEvent = new object();
106 		static readonly object SortedEvent = new object();
107 		static readonly object SortingEvent = new object();
108 
109 		// Control state
110 		int pageIndex;
111 		int selectedIndex = -1;
112 		int editIndex = -1;
113 		int pageCount = 0;
114 		SortDirection sortDirection = SortDirection.Ascending;
115 		string sortExpression;
116 
GridView()117 		public GridView ()
118 		{
119 			EnableModelValidation = true;
120 		}
121 
122 		public event EventHandler PageIndexChanged {
123 			add { Events.AddHandler (PageIndexChangedEvent, value); }
124 			remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
125 		}
126 
127 		public event GridViewPageEventHandler PageIndexChanging {
128 			add { Events.AddHandler (PageIndexChangingEvent, value); }
129 			remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
130 		}
131 
132 		public event GridViewCancelEditEventHandler RowCancelingEdit {
133 			add { Events.AddHandler (RowCancelingEditEvent, value); }
134 			remove { Events.RemoveHandler (RowCancelingEditEvent, value); }
135 		}
136 
137 		public event GridViewCommandEventHandler RowCommand {
138 			add { Events.AddHandler (RowCommandEvent, value); }
139 			remove { Events.RemoveHandler (RowCommandEvent, value); }
140 		}
141 
142 		public event GridViewRowEventHandler RowCreated {
143 			add { Events.AddHandler (RowCreatedEvent, value); }
144 			remove { Events.RemoveHandler (RowCreatedEvent, value); }
145 		}
146 
147 		public event GridViewRowEventHandler RowDataBound {
148 			add { Events.AddHandler (RowDataBoundEvent, value); }
149 			remove { Events.RemoveHandler (RowDataBoundEvent, value); }
150 		}
151 
152 		public event GridViewDeletedEventHandler RowDeleted {
153 			add { Events.AddHandler (RowDeletedEvent, value); }
154 			remove { Events.RemoveHandler (RowDeletedEvent, value); }
155 		}
156 
157 		public event GridViewDeleteEventHandler RowDeleting {
158 			add { Events.AddHandler (RowDeletingEvent, value); }
159 			remove { Events.RemoveHandler (RowDeletingEvent, value); }
160 		}
161 
162 		public event GridViewEditEventHandler RowEditing {
163 			add { Events.AddHandler (RowEditingEvent, value); }
164 			remove { Events.RemoveHandler (RowEditingEvent, value); }
165 		}
166 
167 		public event GridViewUpdatedEventHandler RowUpdated {
168 			add { Events.AddHandler (RowUpdatedEvent, value); }
169 			remove { Events.RemoveHandler (RowUpdatedEvent, value); }
170 		}
171 
172 		public event GridViewUpdateEventHandler RowUpdating {
173 			add { Events.AddHandler (RowUpdatingEvent, value); }
174 			remove { Events.RemoveHandler (RowUpdatingEvent, value); }
175 		}
176 
177 		public event EventHandler SelectedIndexChanged {
178 			add { Events.AddHandler (SelectedIndexChangedEvent, value); }
179 			remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
180 		}
181 
182 		public event GridViewSelectEventHandler SelectedIndexChanging {
183 			add { Events.AddHandler (SelectedIndexChangingEvent, value); }
184 			remove { Events.RemoveHandler (SelectedIndexChangingEvent, value); }
185 		}
186 
187 		public event EventHandler Sorted {
188 			add { Events.AddHandler (SortedEvent, value); }
189 			remove { Events.RemoveHandler (SortedEvent, value); }
190 		}
191 
192 		public event GridViewSortEventHandler Sorting {
193 			add { Events.AddHandler (SortingEvent, value); }
194 			remove { Events.RemoveHandler (SortingEvent, value); }
195 		}
196 
OnPageIndexChanged(EventArgs e)197 		protected virtual void OnPageIndexChanged (EventArgs e)
198 		{
199 			if (Events != null) {
200 				EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
201 				if (eh != null) eh (this, e);
202 			}
203 		}
204 
OnPageIndexChanging(GridViewPageEventArgs e)205 		protected virtual void OnPageIndexChanging (GridViewPageEventArgs e)
206 		{
207 			if (Events != null) {
208 				GridViewPageEventHandler eh = (GridViewPageEventHandler) Events [PageIndexChangingEvent];
209 				if (eh != null) {
210 					eh (this, e);
211 					return;
212 				}
213 			}
214 			if (!IsBoundUsingDataSourceID)
215 				throw new HttpException (String.Format ("The GridView '{0}' fired event PageIndexChanging which wasn't handled.", ID));
216 		}
217 
OnRowCancelingEdit(GridViewCancelEditEventArgs e)218 		protected virtual void OnRowCancelingEdit (GridViewCancelEditEventArgs e)
219 		{
220 			if (Events != null) {
221 				GridViewCancelEditEventHandler eh = (GridViewCancelEditEventHandler) Events [RowCancelingEditEvent];
222 				if (eh != null) {
223 					eh (this, e);
224 					return;
225 				}
226 			}
227 			if (!IsBoundUsingDataSourceID)
228 				throw new HttpException (String.Format ("The GridView '{0}' fired event RowCancelingEdit which wasn't handled.", ID));
229 		}
230 
OnRowCommand(GridViewCommandEventArgs e)231 		protected virtual void OnRowCommand (GridViewCommandEventArgs e)
232 		{
233 			if (Events != null) {
234 				GridViewCommandEventHandler eh = (GridViewCommandEventHandler) Events [RowCommandEvent];
235 				if (eh != null) eh (this, e);
236 			}
237 		}
238 
OnRowCreated(GridViewRowEventArgs e)239 		protected virtual void OnRowCreated (GridViewRowEventArgs e)
240 		{
241 			if (Events != null) {
242 				GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowCreatedEvent];
243 				if (eh != null) eh (this, e);
244 			}
245 		}
246 
OnRowDataBound(GridViewRowEventArgs e)247 		protected virtual void OnRowDataBound (GridViewRowEventArgs e)
248 		{
249 			if (Events != null) {
250 				GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowDataBoundEvent];
251 				if (eh != null) eh (this, e);
252 			}
253 		}
254 
OnRowDeleted(GridViewDeletedEventArgs e)255 		protected virtual void OnRowDeleted (GridViewDeletedEventArgs e)
256 		{
257 			if (Events != null) {
258 				GridViewDeletedEventHandler eh = (GridViewDeletedEventHandler) Events [RowDeletedEvent];
259 				if (eh != null) eh (this, e);
260 			}
261 		}
262 
OnRowDeleting(GridViewDeleteEventArgs e)263 		protected virtual void OnRowDeleting (GridViewDeleteEventArgs e)
264 		{
265 			if (Events != null) {
266 				GridViewDeleteEventHandler eh = (GridViewDeleteEventHandler) Events [RowDeletingEvent];
267 				if (eh != null) {
268 					eh (this, e);
269 					return;
270 				}
271 			}
272 			if (!IsBoundUsingDataSourceID)
273 				throw new HttpException (String.Format ("The GridView '{0}' fired event RowDeleting which wasn't handled.", ID));
274 		}
275 
OnRowEditing(GridViewEditEventArgs e)276 		protected virtual void OnRowEditing (GridViewEditEventArgs e)
277 		{
278 			if (Events != null) {
279 				GridViewEditEventHandler eh = (GridViewEditEventHandler) Events [RowEditingEvent];
280 				if (eh != null) {
281 					eh (this, e);
282 					return;
283 				}
284 			}
285 			if (!IsBoundUsingDataSourceID)
286 				throw new HttpException (String.Format ("The GridView '{0}' fired event RowEditing which wasn't handled.", ID));
287 		}
288 
OnRowUpdated(GridViewUpdatedEventArgs e)289 		protected virtual void OnRowUpdated (GridViewUpdatedEventArgs e)
290 		{
291 			if (Events != null) {
292 				GridViewUpdatedEventHandler eh = (GridViewUpdatedEventHandler) Events [RowUpdatedEvent];
293 				if (eh != null) eh (this, e);
294 			}
295 		}
296 
OnRowUpdating(GridViewUpdateEventArgs e)297 		protected virtual void OnRowUpdating (GridViewUpdateEventArgs e)
298 		{
299 			if (Events != null) {
300 				GridViewUpdateEventHandler eh = (GridViewUpdateEventHandler) Events [RowUpdatingEvent];
301 				if (eh != null) {
302 					eh (this, e);
303 					return;
304 				}
305 			}
306 			if (!IsBoundUsingDataSourceID)
307 				throw new HttpException (String.Format ("The GridView '{0}' fired event RowUpdating which wasn't handled.", ID));
308 		}
309 
OnSelectedIndexChanged(EventArgs e)310 		protected virtual void OnSelectedIndexChanged (EventArgs e)
311 		{
312 			if (Events != null) {
313 				EventHandler eh = (EventHandler) Events [SelectedIndexChangedEvent];
314 				if (eh != null) eh (this, e);
315 			}
316 		}
317 
OnSelectedIndexChanging(GridViewSelectEventArgs e)318 		protected virtual void OnSelectedIndexChanging (GridViewSelectEventArgs e)
319 		{
320 			if (Events != null) {
321 				GridViewSelectEventHandler eh = (GridViewSelectEventHandler) Events [SelectedIndexChangingEvent];
322 				if (eh != null) eh (this, e);
323 			}
324 		}
325 
OnSorted(EventArgs e)326 		protected virtual void OnSorted (EventArgs e)
327 		{
328 			if (Events != null) {
329 				EventHandler eh = (EventHandler) Events [SortedEvent];
330 				if (eh != null) eh (this, e);
331 			}
332 		}
333 
OnSorting(GridViewSortEventArgs e)334 		protected virtual void OnSorting (GridViewSortEventArgs e)
335 		{
336 			if (Events != null) {
337 				GridViewSortEventHandler eh = (GridViewSortEventHandler) Events [SortingEvent];
338 				if (eh != null) {
339 					eh (this, e);
340 					return;
341 				}
342 			}
343 			if (!IsBoundUsingDataSourceID)
344 				throw new HttpException (String.Format ("The GridView '{0}' fired event Sorting which wasn't handled.", ID));
345 		}
346 
347 
348 		[WebCategoryAttribute ("Paging")]
349 		[DefaultValueAttribute (false)]
350 		public virtual bool AllowPaging {
351 			get {
352 				object ob = ViewState ["AllowPaging"];
353 				if (ob != null)
354 					return (bool) ob;
355 				return false;
356 			}
357 			set {
358 				if (value == AllowPaging)
359 					return;
360 				ViewState ["AllowPaging"] = value;
361 				RequireBinding ();
362 			}
363 		}
364 
365 		[WebCategoryAttribute ("Behavior")]
366 		[DefaultValueAttribute (false)]
367 		public virtual bool AllowSorting {
368 			get {
369 				object ob = ViewState ["AllowSorting"];
370 				if (ob != null)
371 					return (bool) ob;
372 				return false;
373 			}
374 			set {
375 				if (value == AllowSorting)
376 					return;
377 				ViewState ["AllowSorting"] = value;
378 				RequireBinding ();
379 			}
380 		}
381 
382 		[WebCategoryAttribute ("Styles")]
383 		[PersistenceMode (PersistenceMode.InnerProperty)]
384 		[NotifyParentProperty (true)]
385 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
386 		public TableItemStyle AlternatingRowStyle {
387 			get {
388 				if (alternatingRowStyle == null) {
389 					alternatingRowStyle = new TableItemStyle ();
390 					if (IsTrackingViewState)
391 						alternatingRowStyle.TrackViewState();
392 				}
393 				return alternatingRowStyle;
394 			}
395 		}
396 
397 		[WebCategoryAttribute ("Behavior")]
398 		[DefaultValueAttribute (false)]
399 		public virtual bool AutoGenerateEditButton {
400 			get {
401 				object ob = ViewState ["AutoGenerateEditButton"];
402 				if (ob != null)
403 					return (bool) ob;
404 				return false;
405 			}
406 			set {
407 				if (value == AutoGenerateEditButton)
408 					return;
409 				ViewState ["AutoGenerateEditButton"] = value;
410 				RequireBinding ();
411 			}
412 		}
413 
414 		[WebCategoryAttribute ("Behavior")]
415 		[DefaultValueAttribute (false)]
416 		public virtual bool AutoGenerateDeleteButton {
417 			get {
418 				object ob = ViewState ["AutoGenerateDeleteButton"];
419 				if (ob != null)
420 					return (bool) ob;
421 				return false;
422 			}
423 			set {
424 				if (value == AutoGenerateDeleteButton)
425 					return;
426 				ViewState ["AutoGenerateDeleteButton"] = value;
427 				RequireBinding ();
428 			}
429 		}
430 
431 		[WebCategoryAttribute ("Behavior")]
432 		[DefaultValueAttribute (false)]
433 		public virtual bool AutoGenerateSelectButton {
434 			get {
435 				object ob = ViewState ["AutoGenerateSelectButton"];
436 				if (ob != null)
437 					return (bool) ob;
438 				return false;
439 			}
440 			set {
441 				if (value == AutoGenerateSelectButton)
442 					return;
443 				ViewState ["AutoGenerateSelectButton"] = value;
444 				RequireBinding ();
445 			}
446 		}
447 
448 		[WebCategoryAttribute ("Behavior")]
449 		[DefaultValueAttribute (true)]
450 		public virtual bool AutoGenerateColumns {
451 			get {
452 				object ob = ViewState ["AutoGenerateColumns"];
453 				if (ob != null)
454 					return (bool) ob;
455 				return true;
456 			}
457 			set {
458 				if (value == AutoGenerateColumns)
459 					return;
460 				ViewState ["AutoGenerateColumns"] = value;
461 				RequireBinding ();
462 			}
463 		}
464 
465 		[UrlPropertyAttribute]
466 		[WebCategoryAttribute ("Appearance")]
467 		[DefaultValueAttribute ("")]
468 		[EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
469 		public virtual string BackImageUrl {
470 			get {
471 				if (ControlStyleCreated)
472 					return ((TableStyle) ControlStyle).BackImageUrl;
473 				return String.Empty;
474 			}
475 			set { ((TableStyle) ControlStyle).BackImageUrl = value; }
476 		}
477 
478 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
479 		[BrowsableAttribute (false)]
480 		public virtual GridViewRow BottomPagerRow {
481 			get {
482 				EnsureDataBound ();
483 				return bottomPagerRow;
484 			}
485 		}
486 
487 		[WebCategoryAttribute ("Accessibility")]
488 		[DefaultValueAttribute ("")]
489 		[LocalizableAttribute (true)]
490 		public virtual string Caption {
491 			get {
492 				object ob = ViewState ["Caption"];
493 				if (ob != null)
494 					return (string) ob;
495 				return String.Empty;
496 			}
497 			set { ViewState ["Caption"] = value; }
498 		}
499 
500 		[WebCategoryAttribute ("Accessibility")]
501 		[DefaultValueAttribute (TableCaptionAlign.NotSet)]
502 		public virtual TableCaptionAlign CaptionAlign
503 		{
504 			get {
505 				object o = ViewState ["CaptionAlign"];
506 				if(o != null)
507 					return (TableCaptionAlign) o;
508 				return TableCaptionAlign.NotSet;
509 			}
510 			set { ViewState ["CaptionAlign"] = value; }
511 		}
512 
513 		[WebCategoryAttribute ("Layout")]
514 		[DefaultValueAttribute (-1)]
515 		public virtual int CellPadding
516 		{
517 			get {
518 				if (ControlStyleCreated)
519 					return ((TableStyle) ControlStyle).CellPadding;
520 				return -1;
521 			}
522 			set { ((TableStyle) ControlStyle).CellPadding = value; }
523 		}
524 
525 		[WebCategoryAttribute ("Layout")]
526 		[DefaultValueAttribute (0)]
527 		public virtual int CellSpacing
528 		{
529 			get {
530 				if (ControlStyleCreated)
531 					return ((TableStyle) ControlStyle).CellSpacing;
532 				return 0;
533 			}
534 			set { ((TableStyle) ControlStyle).CellSpacing = value; }
535 		}
536 
537 		[EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
538 		[MergablePropertyAttribute (false)]
539 		[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
540 		[DefaultValueAttribute (null)]
541 		[WebCategoryAttribute ("Misc")]
542 		public virtual DataControlFieldCollection Columns {
543 			get {
544 				if (columns == null) {
545 					columns = new DataControlFieldCollection ();
546 					columns.FieldsChanged += new EventHandler (OnFieldsChanged);
547 					if (IsTrackingViewState)
548 						((IStateManager)columns).TrackViewState ();
549 				}
550 				return columns;
551 			}
552 		}
553 
554 		[BrowsableAttribute(false)]
555 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
556 		public IAutoFieldGenerator ColumnsGenerator {
557 			get;
558 			set;
559 		}
560 
561 		[DefaultValueAttribute (null)]
562 		[WebCategoryAttribute ("Data")]
563 		[TypeConverter (typeof(StringArrayConverter))]
564 		[EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
565 		public virtual string[] DataKeyNames {
566 			get {
567 				if (dataKeyNames != null)
568 					return dataKeyNames;
569 				return emptyKeys;
570 			}
571 			set {
572 				dataKeyNames = value;
573 				RequireBinding ();
574 			}
575 		}
576 
577 		List <DataKey> DataKeyList {
578 			get {
579 				if (_dataKeyList == null)
580 					_dataKeyList = new List <DataKey> ();
581 
582 				return _dataKeyList;
583 			}
584 		}
585 		List <DataKey> DataKeySuffixList {
586 			get {
587 				if (_dataKeySuffixList == null)
588 					_dataKeySuffixList = new List <DataKey> ();
589 
590 				return _dataKeySuffixList;
591 			}
592 		}
593 		[BrowsableAttribute (false)]
594 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
595 		public virtual DataKeyArray DataKeys {
596 			get {
597 				if (keys == null) {
598 					keys = new DataKeyArray (DataKeyList);
599 					if (IsTrackingViewState)
600 						((IStateManager) keys).TrackViewState ();
601 				}
602 				return keys;
603 			}
604 		}
605 
606 		DataKey OldEditValues {
607 			get {
608 				if (oldEditValues == null) {
609 					oldEditValues = new DataKey (new OrderedDictionary ());
610 				}
611 				return oldEditValues;
612 			}
613 		}
614 
615 		[WebCategoryAttribute ("Misc")]
616 		[DefaultValueAttribute (-1)]
617 		public virtual int EditIndex {
618 			get { return editIndex; }
619 			set {
620 				if (value == editIndex)
621 					return;
622 				editIndex = value;
623 				RequireBinding ();
624 			}
625 		}
626 
627 		[WebCategoryAttribute ("Styles")]
628 		[PersistenceMode (PersistenceMode.InnerProperty)]
629 		[NotifyParentProperty (true)]
630 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
631 		public TableItemStyle EditRowStyle {
632 			get {
633 				if (editRowStyle == null) {
634 					editRowStyle = new TableItemStyle ();
635 					if (IsTrackingViewState)
636 						editRowStyle.TrackViewState();
637 				}
638 				return editRowStyle;
639 			}
640 		}
641 
642 		[WebCategoryAttribute ("Styles")]
643 		[PersistenceMode (PersistenceMode.InnerProperty)]
644 		[NotifyParentProperty (true)]
645 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
646 		public TableItemStyle EmptyDataRowStyle {
647 			get {
648 				if (emptyDataRowStyle == null) {
649 					emptyDataRowStyle = new TableItemStyle ();
650 					if (IsTrackingViewState)
651 						emptyDataRowStyle.TrackViewState();
652 				}
653 				return emptyDataRowStyle;
654 			}
655 		}
656 
657 		[DefaultValue (null)]
658 		[TemplateContainer (typeof(GridViewRow), BindingDirection.OneWay)]
659 		[PersistenceMode (PersistenceMode.InnerProperty)]
660 		[Browsable (false)]
661 		public virtual ITemplate EmptyDataTemplate {
662 			get { return emptyDataTemplate; }
663 			set { emptyDataTemplate = value; }
664 		}
665 
666 		[LocalizableAttribute (true)]
667 		[WebCategoryAttribute ("Appearance")]
668 		[DefaultValueAttribute ("")]
669 		public virtual string EmptyDataText {
670 			get {
671 				object ob = ViewState ["EmptyDataText"];
672 				if (ob != null)
673 					return (string) ob;
674 				return String.Empty;
675 			}
676 			set {
677 				if (value == EmptyDataText)
678 					return;
679 				ViewState ["EmptyDataText"] = value;
680 				RequireBinding ();
681 			}
682 		}
683 
684 		[WebCategoryAttribute ("Behavior")]
685 		[DefaultValueAttribute (false)]
686 		public virtual bool EnableSortingAndPagingCallbacks {
687 			get {
688 				object ob = ViewState ["EnableSortingAndPagingCallbacks"];
689 				if (ob != null)
690 					return (bool) ob;
691 				return false;
692 			}
693 			set {
694 				if (value == EnableSortingAndPagingCallbacks)
695 					return;
696 				ViewState ["EnableSortingAndPagingCallbacks"] = value;
697 				RequireBinding ();
698 			}
699 		}
700 
701 		[MonoTODO ("Make use of it in the code")]
702 		[DefaultValue (true)]
703 		public virtual bool EnableModelValidation {
704 			get;
705 			set;
706 		}
707 
708 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
709 		[BrowsableAttribute (false)]
710 		public virtual GridViewRow FooterRow {
711 			get {
712 				if (table != null) {
713 					for (int index = table.Rows.Count - 1; index >= 0; index--) {
714 						GridViewRow row = (GridViewRow) table.Rows [index];
715 						switch (row.RowType) {
716 							case DataControlRowType.Separator:
717 							case DataControlRowType.Pager:
718 								continue;
719 							case DataControlRowType.Footer:
720 								return row;
721 							default:
722 								break;
723 						}
724 					}
725 				}
726 				return null;
727 			}
728 		}
729 
730 		[WebCategoryAttribute ("Styles")]
731 		[PersistenceMode (PersistenceMode.InnerProperty)]
732 		[NotifyParentProperty (true)]
733 		[DefaultValue (null)]
734 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
735 		public TableItemStyle FooterStyle {
736 			get {
737 				if (footerStyle == null) {
738 					footerStyle = new TableItemStyle ();
739 					if (IsTrackingViewState)
740 						footerStyle.TrackViewState();
741 				}
742 				return footerStyle;
743 			}
744 		}
745 
746 		[WebCategoryAttribute ("Appearance")]
747 		[DefaultValueAttribute (GridLines.Both)]
748 		public virtual GridLines GridLines {
749 			get {
750 				if (ControlStyleCreated)
751 					return ((TableStyle) ControlStyle).GridLines;
752 				return GridLines.Both;
753 			}
754 			set { ((TableStyle) ControlStyle).GridLines = value; }
755 		}
756 
757 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
758 		[BrowsableAttribute (false)]
759 		public virtual GridViewRow HeaderRow {
760 			get {
761 				if (table != null) {
762 					for (int index = 0, total = table.Rows.Count; index < total; index++) {
763 						GridViewRow row = (GridViewRow) table.Rows [index];
764 						switch (row.RowType) {
765 							case DataControlRowType.Separator:
766 							case DataControlRowType.Pager:
767 								continue;
768 							case DataControlRowType.Header:
769 								return row;
770 							default:
771 								break;
772 						}
773 					}
774 				}
775 				return null;
776 			}
777 		}
778 
779 		[WebCategoryAttribute ("Styles")]
780 		[PersistenceMode (PersistenceMode.InnerProperty)]
781 		[NotifyParentProperty (true)]
782 		[DefaultValue (null)]
783 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
784 		public TableItemStyle HeaderStyle {
785 			get {
786 				if (headerStyle == null) {
787 					headerStyle = new TableItemStyle ();
788 					if (IsTrackingViewState)
789 						headerStyle.TrackViewState();
790 				}
791 				return headerStyle;
792 			}
793 		}
794 
795 		[Category ("Layout")]
796 		[DefaultValueAttribute (HorizontalAlign.NotSet)]
797 		public virtual HorizontalAlign HorizontalAlign {
798 			get {
799 				if (ControlStyleCreated)
800 					return ((TableStyle) ControlStyle).HorizontalAlign;
801 				return HorizontalAlign.NotSet;
802 			}
803 			set { ((TableStyle) ControlStyle).HorizontalAlign = value; }
804 		}
805 
806 		[BrowsableAttribute (false)]
807 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
808 		public virtual int PageCount {
809 			get { return pageCount; }
810 			private set { pageCount = value; }
811 		}
812 
813 		[WebCategoryAttribute ("Paging")]
814 		[BrowsableAttribute (true)]
815 		[DefaultValueAttribute (0)]
816 		public virtual int PageIndex {
817 			get { return pageIndex; }
818 			set {
819 				if (value == pageIndex)
820 					return;
821 				pageIndex = value;
822 				RequireBinding ();
823 			}
824 		}
825 
826 		[DefaultValueAttribute (10)]
827 		[WebCategoryAttribute ("Paging")]
828 		public virtual int PageSize {
829 			get {
830 				object ob = ViewState ["PageSize"];
831 				if (ob != null)
832 					return (int) ob;
833 				return 10;
834 			}
835 			set {
836 				if (value == PageSize)
837 					return;
838 				ViewState ["PageSize"] = value;
839 				RequireBinding ();
840 			}
841 		}
842 
843 		[WebCategoryAttribute ("Paging")]
844 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
845 		[NotifyParentPropertyAttribute (true)]
846 		[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
847 		public virtual PagerSettings PagerSettings {
848 			get {
849 				if (pagerSettings == null) {
850 					pagerSettings = new PagerSettings (this);
851 					if (IsTrackingViewState)
852 						((IStateManager)pagerSettings).TrackViewState ();
853 				}
854 				return pagerSettings;
855 			}
856 		}
857 
858 		[WebCategoryAttribute ("Styles")]
859 		[PersistenceMode (PersistenceMode.InnerProperty)]
860 		[NotifyParentProperty (true)]
861 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
862 		public TableItemStyle PagerStyle {
863 			get {
864 				if (pagerStyle == null) {
865 					pagerStyle = new TableItemStyle ();
866 					if (IsTrackingViewState)
867 						pagerStyle.TrackViewState();
868 				}
869 				return pagerStyle;
870 			}
871 		}
872 
873 
874 		[DefaultValue (null)]
875 		[PersistenceMode (PersistenceMode.InnerProperty)]
876 		[Browsable (false)]
877 		[TemplateContainerAttribute(typeof(GridViewRow))]
878 		public virtual ITemplate PagerTemplate {
879 			get { return pagerTemplate; }
880 			set { pagerTemplate = value; }
881 		}
882 
883 		[DefaultValueAttribute ("")]
884 		[WebCategoryAttribute ("Accessibility")]
885 		//		[TypeConverterAttribute (typeof(System.Web.UI.Design.DataColumnSelectionConverter)]
886 		public virtual string RowHeaderColumn {
887 			get {
888 				object ob = ViewState ["RowHeaderColumn"];
889 				if (ob != null)
890 					return (string) ob;
891 				return String.Empty;
892 			}
893 			set {
894 				if (value == RowHeaderColumn)
895 					return;
896 				ViewState ["RowHeaderColumn"] = value;
897 				RequireBinding ();
898 			}
899 		}
900 
901 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
902 		[BrowsableAttribute (false)]
903 		public virtual GridViewRowCollection Rows {
904 			get {
905 				EnsureChildControls ();
906 				if (rows == null)
907 					rows = new GridViewRowCollection (new ArrayList ());
908 				return rows;
909 			}
910 		}
911 
912 		[WebCategoryAttribute ("Styles")]
913 		[PersistenceMode (PersistenceMode.InnerProperty)]
914 		[NotifyParentProperty (true)]
915 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
916 		public TableItemStyle RowStyle {
917 			get {
918 				if (rowStyle == null) {
919 					rowStyle = new TableItemStyle ();
920 					if (IsTrackingViewState)
921 						rowStyle.TrackViewState();
922 				}
923 				return rowStyle;
924 			}
925 		}
926 
927 		[BrowsableAttribute (false)]
928 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
929 		public virtual DataKey SelectedDataKey {
930 			get {
931 				if (DataKeyNames.Length == 0)
932 					throw new InvalidOperationException (String.Format ("Data keys must be specified on GridView '{0}' before the selected data keys can be retrieved.  Use the DataKeyNames property to specify data keys.", ID));
933 
934 				if (selectedIndex >= 0 && selectedIndex < DataKeys.Count)
935 					return DataKeys [selectedIndex];
936 				else
937 					return null;
938 			}
939 		}
940 
941 		[MonoTODO]
942 		[Browsable(false)]
943 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
944 		public virtual DataKey SelectedPersistedDataKey {
945 			get; set;
946 		}
947 
948 		[MonoTODO]
949 		DataKey IPersistedSelector.DataKey {
950 			get { return SelectedPersistedDataKey; }
951 			set { SelectedPersistedDataKey = value; }
952 		}
953 
954 		[BindableAttribute (true)]
955 		[DefaultValueAttribute (-1)]
956 		public virtual int SelectedIndex {
957 			get { return selectedIndex; }
958 			set {
959 				if (rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count) {
960 					int oldIndex = selectedIndex;
961 					selectedIndex = -1;
962 					Rows [oldIndex].RowState = GetRowState (oldIndex);
963 				}
964 				selectedIndex = value;
965 				if (rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count)
966 					Rows [selectedIndex].RowState = GetRowState (selectedIndex);
967 			}
968 		}
969 
970 		[BrowsableAttribute (false)]
971 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
972 		public virtual GridViewRow SelectedRow {
973 			get {
974 				if (selectedIndex >= 0 && selectedIndex < Rows.Count)
975 					return Rows [selectedIndex];
976 				else
977 					return null;
978 			}
979 		}
980 
981 		[WebCategoryAttribute ("Styles")]
982 		[PersistenceMode (PersistenceMode.InnerProperty)]
983 		[NotifyParentProperty (true)]
984 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
985 		public TableItemStyle SelectedRowStyle {
986 			get {
987 				if (selectedRowStyle == null) {
988 					selectedRowStyle = new TableItemStyle ();
989 					if (IsTrackingViewState)
990 						selectedRowStyle.TrackViewState();
991 				}
992 				return selectedRowStyle;
993 			}
994 		}
995 
996 		[BrowsableAttribute (false)]
997 		public object SelectedValue {
998 			get {
999 				if (SelectedDataKey != null)
1000 					return SelectedDataKey.Value;
1001 				else
1002 					return null;
1003 			}
1004 		}
1005 
1006 		[WebCategoryAttribute ("Appearance")]
1007 		[DefaultValueAttribute (false)]
1008 		public virtual bool ShowFooter {
1009 			get {
1010 				object ob = ViewState ["ShowFooter"];
1011 				if (ob != null)
1012 					return (bool) ob;
1013 				return false;
1014 			}
1015 			set {
1016 				if (value == ShowFooter)
1017 					return;
1018 				ViewState ["ShowFooter"] = value;
1019 				RequireBinding ();
1020 			}
1021 		}
1022 
1023 		[WebCategoryAttribute ("Appearance")]
1024 		[DefaultValueAttribute (true)]
1025 		public virtual bool ShowHeader {
1026 			get {
1027 				object ob = ViewState ["ShowHeader"];
1028 				if (ob != null)
1029 					return (bool) ob;
1030 				return true;
1031 			}
1032 			set {
1033 				if (value == ShowHeader)
1034 					return;
1035 				ViewState ["ShowHeader"] = value;
1036 				RequireBinding ();
1037 			}
1038 		}
1039 
1040 		[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
1041 		[BrowsableAttribute (false)]
1042 		[DefaultValueAttribute (SortDirection.Ascending)]
1043 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1044 		public virtual SortDirection SortDirection {
1045 			get { return sortDirection; }
1046 			private set {
1047 				if (sortDirection == value)
1048 					return;
1049 				sortDirection = value;
1050 				RequireBinding ();
1051 			}
1052 		}
1053 
1054 		[BrowsableAttribute (false)]
1055 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1056 		public virtual string SortExpression {
1057 			get {
1058 				if (sortExpression == null)
1059 					return String.Empty;
1060 				return sortExpression;
1061 			}
1062 			private set {
1063 				if (sortExpression == value)
1064 					return;
1065 				sortExpression = value;
1066 				RequireBinding ();
1067 			}
1068 		}
1069 
1070 		[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1071 		[BrowsableAttribute (false)]
1072 		public virtual GridViewRow TopPagerRow {
1073 			get {
1074 				EnsureDataBound ();
1075 				return topPagerRow;
1076 			}
1077 		}
1078 
1079 		[WebCategoryAttribute ("Accessibility")]
1080 		[DefaultValueAttribute (true)]
1081 		public virtual bool UseAccessibleHeader {
1082 			get {
1083 				object ob = ViewState ["UseAccessibleHeader"];
1084 				if (ob != null)
1085 					return (bool) ob;
1086 				return true;
1087 			}
1088 			set {
1089 				if (value == UseAccessibleHeader)
1090 					return;
1091 				ViewState ["UseAccessibleHeader"] = value;
1092 				RequireBinding ();
1093 			}
1094 		}
1095 		[TypeConverter (typeof(StringArrayConverter))]
1096 		[DefaultValue (null)]
1097 		public virtual string[] ClientIDRowSuffix {
1098 			get;
1099 			set;
1100 		}
1101 
1102 		[BrowsableAttribute(false)]
1103 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1104 		public DataKeyArray ClientIDRowSuffixDataKeys {
1105 			get {
1106 				if (rowSuffixKeys == null) {
1107 					rowSuffixKeys = new DataKeyArray (DataKeySuffixList);
1108 					if (IsTrackingViewState)
1109 						((IStateManager) rowSuffixKeys).TrackViewState ();
1110 				}
1111 
1112 				return rowSuffixKeys;
1113 			}
1114 		}
1115 
1116 		[DefaultValue (false)]
1117 		public virtual bool EnablePersistedSelection {
1118 			get {
1119 				throw new NotImplementedException ();
1120 			}
1121 
1122 			set {
1123 				throw new NotImplementedException ();
1124 			}
1125 		}
1126 
1127 		IAutoFieldGenerator IFieldControl.FieldsGenerator {
1128 			get {
1129 				throw new NotImplementedException ();
1130 			}
1131 
1132 			set {
1133 				throw new NotImplementedException ();
1134 			}
1135 		}
1136 
1137 		[DefaultValue (false)]
1138 		public virtual bool ShowHeaderWhenEmpty {
1139 			get { return ViewState.GetBool ("ShowHeaderWhenEmpty", false); }
1140 			set {
1141 				if (value == ShowHeaderWhenEmpty)
1142 					return;
1143 
1144 				ViewState ["ShowHeaderWhenEmpty"] = value;
1145 				RequireBinding ();
1146 			}
1147 		}
1148 
1149 		[PersistenceMode (PersistenceMode.InnerProperty)]
1150 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1151 		[NotifyParentProperty (true)]
1152 		public TableItemStyle SortedAscendingCellStyle {
1153 			get {
1154 				if (sortedAscendingCellStyle == null) {
1155 					sortedAscendingCellStyle = new TableItemStyle ();
1156 					if (IsTrackingViewState)
1157 						((IStateManager)sortedAscendingCellStyle).TrackViewState ();
1158 				}
1159 
1160 				return sortedAscendingCellStyle;
1161 			}
1162 		}
1163 
1164 		[PersistenceMode (PersistenceMode.InnerProperty)]
1165 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1166 		[NotifyParentProperty (true)]
1167 		public TableItemStyle SortedAscendingHeaderStyle {
1168 			get {
1169 				if (sortedAscendingHeaderStyle == null) {
1170 					sortedAscendingHeaderStyle = new TableItemStyle ();
1171 					if (IsTrackingViewState)
1172 						((IStateManager)sortedAscendingHeaderStyle).TrackViewState ();
1173 				}
1174 
1175 				return sortedAscendingHeaderStyle;
1176 			}
1177 		}
1178 
1179 		[PersistenceMode (PersistenceMode.InnerProperty)]
1180 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1181 		[NotifyParentProperty (true)]
1182 		public TableItemStyle SortedDescendingCellStyle {
1183 			get {
1184 				if (sortedDescendingCellStyle == null) {
1185 					sortedDescendingCellStyle = new TableItemStyle ();
1186 					if (IsTrackingViewState)
1187 						((IStateManager)sortedDescendingCellStyle).TrackViewState ();
1188 				}
1189 
1190 				return sortedDescendingCellStyle;
1191 			}
1192 		}
1193 
1194 		[PersistenceMode (PersistenceMode.InnerProperty)]
1195 		[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1196 		[NotifyParentProperty (true)]
1197 		public TableItemStyle SortedDescendingHeaderStyle {
1198 			get {
1199 				if (sortedDescendingHeaderStyle == null) {
1200 					sortedDescendingHeaderStyle = new TableItemStyle ();
1201 					if (IsTrackingViewState)
1202 						((IStateManager)sortedDescendingHeaderStyle).TrackViewState ();
1203 				}
1204 
1205 				return sortedDescendingHeaderStyle;
1206 			}
1207 		}
IsBindableType(Type type)1208 		public virtual bool IsBindableType (Type type)
1209 		{
1210 			return type.IsPrimitive || type == typeof (string) || type == typeof (decimal) || type == typeof (DateTime) || type == typeof (Guid);
1211 		}
1212 
1213 		// MSDN: The CreateDataSourceSelectArguments method is a helper method called by
1214 		// the GridView control to create the DataSourceSelectArguments object that
1215 		// contains the arguments passed to the data source. In this implementation,
1216 		// the DataSourceSelectArguments object contains the arguments for paging operations.
CreateDataSourceSelectArguments()1217 		protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
1218 		{
1219 			DataSourceSelectArguments arg = DataSourceSelectArguments.Empty;
1220 			DataSourceView view= GetData();
1221 			if (AllowPaging && view.CanPage) {
1222 				arg.StartRowIndex = PageIndex * PageSize;
1223 				if (view.CanRetrieveTotalRowCount) {
1224 					arg.RetrieveTotalRowCount = true;
1225 					arg.MaximumRows = PageSize;
1226 				} else
1227 					arg.MaximumRows = -1;
1228 			}
1229 
1230 			if (IsBoundUsingDataSourceID && !String.IsNullOrEmpty (sortExpression)) {
1231 				if (sortDirection == SortDirection.Ascending)
1232 					arg.SortExpression = sortExpression;
1233 				else
1234 					arg.SortExpression = sortExpression + " DESC";
1235 			}
1236 
1237 			return arg;
1238 		}
1239 
CreateColumns(PagedDataSource dataSource, bool useDataSource)1240 		protected virtual ICollection CreateColumns (PagedDataSource dataSource, bool useDataSource)
1241 		{
1242 			bool autoGenerate = AutoGenerateColumns;
1243 
1244 			if (autoGenerate) {
1245 				IAutoFieldGenerator fieldGenerator = ColumnsGenerator;
1246 				if (fieldGenerator != null)
1247 					return fieldGenerator.GenerateFields (this);
1248 			}
1249 
1250 			ArrayList fields = new ArrayList ();
1251 
1252 			if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateSelectButton) {
1253 				CommandField field = new CommandField ();
1254 				field.ShowEditButton = AutoGenerateEditButton;
1255 				field.ShowDeleteButton = AutoGenerateDeleteButton;
1256 				field.ShowSelectButton = AutoGenerateSelectButton;
1257 				fields.Add (field);
1258 			}
1259 
1260 			fields.AddRange (Columns);
1261 
1262 			if (autoGenerate) {
1263 				if (useDataSource)
1264 					autoFieldProperties = CreateAutoFieldProperties (dataSource);
1265 
1266 				if (autoFieldProperties != null) {
1267 					foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1268 						fields.Add (CreateAutoGeneratedColumn (props));
1269 				}
1270 			}
1271 
1272 			return fields;
1273 		}
1274 
CreateAutoGeneratedColumn(AutoGeneratedFieldProperties fieldProperties)1275 		protected virtual AutoGeneratedField CreateAutoGeneratedColumn (AutoGeneratedFieldProperties fieldProperties)
1276 		{
1277 			return new AutoGeneratedField (fieldProperties);
1278 		}
1279 
CreateAutoFieldProperties(PagedDataSource source)1280 		AutoGeneratedFieldProperties[] CreateAutoFieldProperties (PagedDataSource source)
1281 		{
1282 			if(source == null) return null;
1283 
1284 			PropertyDescriptorCollection props = source.GetItemProperties (new PropertyDescriptor[0]);
1285 			Type prop_type = null;
1286 
1287 			var retVal = new List <AutoGeneratedFieldProperties> ();
1288 
1289 			if (props == null) {
1290 				object fitem = null;
1291 				PropertyInfo prop_item =  source.DataSource.GetType().GetProperty("Item",
1292 												  BindingFlags.Instance | BindingFlags.Static |
1293 												  BindingFlags.Public, null, null,
1294 												  new Type[] { typeof(int) }, null);
1295 
1296 				if (prop_item != null)
1297 					prop_type = prop_item.PropertyType;
1298 
1299 				if (prop_type == null || prop_type == typeof(object)) {
1300 					IEnumerator en = source.GetEnumerator();
1301 					if (en != null && en.MoveNext ()) {
1302 						fitem = en.Current;
1303 						_dataEnumerator = en;
1304 					}
1305 					if (fitem != null)
1306 						prop_type = fitem.GetType();
1307 				}
1308 
1309 				if (fitem != null && fitem is ICustomTypeDescriptor)
1310 					props = TypeDescriptor.GetProperties(fitem);
1311 				else if (prop_type != null) {
1312 					if (IsBindableType (prop_type)) {
1313 						AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1314 						((IStateManager)field).TrackViewState();
1315 						field.Name = "Item";
1316 						field.DataField = BoundField.ThisExpression;
1317 						field.Type = prop_type;
1318 						retVal.Add (field);
1319 					} else
1320 						props = TypeDescriptor.GetProperties (prop_type);
1321 				}
1322 			}
1323 
1324 			if (props != null && props.Count > 0) {
1325 				foreach (PropertyDescriptor current in props) {
1326 					if (IsBindableType (current.PropertyType) && (prop_type == null || current.ComponentType == prop_type)) {
1327 						AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1328 						((IStateManager)field).TrackViewState();
1329 						field.Name = current.Name;
1330 						field.DataField = current.Name;
1331 						for (int i = 0; i < DataKeyNames.Length; i++) {
1332 							if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
1333 								field.IsReadOnly = true;
1334 								break;
1335 							}
1336 						}
1337 						field.Type = current.PropertyType;
1338 						retVal.Add (field);
1339 					}
1340 				}
1341 			}
1342 
1343 			if (retVal.Count > 0)
1344 				return retVal.ToArray ();
1345 			else
1346 				return new AutoGeneratedFieldProperties [0];
1347 		}
1348 
CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)1349 		protected virtual GridViewRow CreateRow (int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
1350 		{
1351 			GridViewRow row = new GridViewRow (rowIndex, dataSourceIndex, rowType, rowState);
1352 			return row;
1353 		}
1354 
RequireBinding()1355 		void RequireBinding ()
1356 		{
1357 			if (Initialized)
1358 				RequiresDataBinding = true;
1359 		}
1360 
CreateChildTable()1361 		protected virtual Table CreateChildTable ()
1362 		{
1363 			return new ContainedTable (this);
1364 		}
1365 
CreateHeaderRow(Table mainTable, DataControlField[] fields, bool dataBinding)1366 		void CreateHeaderRow (Table mainTable, DataControlField[] fields, bool dataBinding)
1367 		{
1368 			GridViewRow headerRow = CreateRow (-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
1369 			InitializeRow (headerRow, fields);
1370 			OnRowCreated (new GridViewRowEventArgs (headerRow));
1371 			mainTable.Rows.Add (headerRow);
1372 			if (dataBinding) {
1373 				headerRow.DataBind ();
1374 				OnRowDataBound (new GridViewRowEventArgs (headerRow));
1375 			}
1376 		}
1377 
CreateChildControls(IEnumerable dataSource, bool dataBinding)1378 		protected override int CreateChildControls (IEnumerable dataSource, bool dataBinding)
1379 		{
1380 			// clear GridView
1381 			Controls.Clear ();
1382 			table = null;
1383 			rows = null;
1384 
1385 			if (dataSource == null)
1386 				return 0;
1387 
1388 			PagedDataSource pagedDataSource;
1389 
1390 			if (dataBinding) {
1391 				DataSourceView view = GetData ();
1392 				pagedDataSource = new PagedDataSource ();
1393 				pagedDataSource.DataSource = dataSource;
1394 
1395 				if (AllowPaging) {
1396 					pagedDataSource.AllowPaging = true;
1397 					pagedDataSource.PageSize = PageSize;
1398 					if (view.CanPage) {
1399 						pagedDataSource.AllowServerPaging = true;
1400 						if (SelectArguments.RetrieveTotalRowCount)
1401 							pagedDataSource.VirtualCount = SelectArguments.TotalRowCount;
1402 					}
1403 					if (PageIndex >= pagedDataSource.PageCount)
1404 						pageIndex = pagedDataSource.PageCount - 1;
1405 					pagedDataSource.CurrentPageIndex = PageIndex;
1406 				}
1407 
1408 				PageCount = pagedDataSource.PageCount;
1409 			} else {
1410 				pagedDataSource = new PagedDataSource ();
1411 				pagedDataSource.DataSource = dataSource;
1412 				if (AllowPaging) {
1413 					pagedDataSource.AllowPaging = true;
1414 					pagedDataSource.PageSize = PageSize;
1415 					pagedDataSource.CurrentPageIndex = PageIndex;
1416 				}
1417 			}
1418 
1419 			bool createPager = AllowPaging && (PageCount >= 1) && PagerSettings.Visible;
1420 
1421 			ArrayList list = new ArrayList ();
1422 
1423 			// Creates the set of fields to show
1424 
1425 			_dataEnumerator = null;
1426 			ICollection fieldCollection = CreateColumns (pagedDataSource, dataBinding);
1427 			int fieldCount = fieldCollection.Count;
1428 			DataControlField dcf;
1429 			DataControlField[] fields = new DataControlField [fieldCount];
1430 			fieldCollection.CopyTo (fields, 0);
1431 
1432 			for (int i = 0; i < fieldCount; i++) {
1433 				dcf = fields [i];
1434 				dcf.Initialize (AllowSorting, this);
1435 				if (EnableSortingAndPagingCallbacks)
1436 					dcf.ValidateSupportsCallback ();
1437 			}
1438 
1439 			bool skip_first = false;
1440 			IEnumerator enumerator;
1441 			if (_dataEnumerator != null) {
1442 				// replaced when creating bound columns
1443 				enumerator = _dataEnumerator;
1444 				skip_first = true;
1445 			} else
1446 				enumerator = pagedDataSource.GetEnumerator ();
1447 
1448 			// Main table creation
1449 			Table mainTable = ContainedTable;
1450 			List <DataKey> dataKeyList;
1451 			string[] dataKeyNames;
1452 			List <DataKey> dataKeySuffixList;
1453 			string[] clientIDRowSuffix;
1454 			if (dataBinding) {
1455 				dataKeyList = DataKeyList;
1456 				dataKeyNames = DataKeyNames;
1457 				dataKeySuffixList = DataKeySuffixList;
1458 				clientIDRowSuffix = ClientIDRowSuffix;
1459 			} else {
1460 				dataKeyList = null;
1461 				dataKeyNames = null;
1462 				dataKeySuffixList = null;
1463 				clientIDRowSuffix = null;
1464 			}
1465 
1466 			while (skip_first || enumerator.MoveNext ()) {
1467 				skip_first = false;
1468 				object obj = enumerator.Current;
1469 
1470 				if (list.Count == 0) {
1471 					if (createPager && (PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom)) {
1472 						topPagerRow = CreatePagerRow (fieldCount, pagedDataSource);
1473 						OnRowCreated (new GridViewRowEventArgs (topPagerRow));
1474 						mainTable.Rows.Add (topPagerRow);
1475 						if (dataBinding) {
1476 							topPagerRow.DataBind ();
1477 							OnRowDataBound (new GridViewRowEventArgs (topPagerRow));
1478 						}
1479 						if (PageCount == 1)
1480 							topPagerRow.Visible = false;
1481 					}
1482 
1483 					if (ShowHeader)
1484 						CreateHeaderRow (mainTable, fields, dataBinding);
1485 				}
1486 
1487 				DataControlRowState rstate = GetRowState (list.Count);
1488 				GridViewRow row = CreateRow (list.Count, list.Count, DataControlRowType.DataRow, rstate);
1489 				row.DataItem = obj;
1490 				list.Add (row);
1491 				InitializeRow (row, fields);
1492 				OnRowCreated (new GridViewRowEventArgs (row));
1493 				mainTable.Rows.Add (row);
1494 				if (dataBinding) {
1495 					row.DataBind ();
1496 					if (EditIndex == row.RowIndex)
1497 						oldEditValues = new DataKey (GetRowValues (row, true, true));
1498 					dataKeyList.Add (new DataKey (CreateRowDataKey (row), dataKeyNames));
1499 					dataKeySuffixList.Add (new DataKey (CreateRowSuffixDataKey (row), clientIDRowSuffix));
1500 					OnRowDataBound (new GridViewRowEventArgs (row));
1501 				}
1502 			}
1503 
1504 			if (list.Count == 0) {
1505  				if (ShowHeader && ShowHeaderWhenEmpty)
1506  					CreateHeaderRow (mainTable, fields, dataBinding);
1507 				GridViewRow emptyRow = CreateEmptyrRow (fieldCount);
1508 				if (emptyRow != null) {
1509 					OnRowCreated (new GridViewRowEventArgs (emptyRow));
1510 					mainTable.Rows.Add (emptyRow);
1511 					if (dataBinding) {
1512 						emptyRow.DataBind ();
1513 						OnRowDataBound (new GridViewRowEventArgs (emptyRow));
1514 					}
1515 				}
1516 				if (mainTable.Rows.Count == 0)
1517 					table = null;
1518 				return 0;
1519 			} else {
1520 				GridViewRow footerRow = CreateRow (-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
1521 				InitializeRow (footerRow, fields);
1522 				OnRowCreated (new GridViewRowEventArgs (footerRow));
1523 				mainTable.Rows.Add (footerRow);
1524 				if (dataBinding) {
1525 					footerRow.DataBind ();
1526 					OnRowDataBound (new GridViewRowEventArgs (footerRow));
1527 				}
1528 
1529 				if (createPager && (PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom)) {
1530 					bottomPagerRow = CreatePagerRow (fieldCount, pagedDataSource);
1531 					OnRowCreated (new GridViewRowEventArgs (bottomPagerRow));
1532 					mainTable.Rows.Add (bottomPagerRow);
1533 					if (dataBinding) {
1534 						bottomPagerRow.DataBind ();
1535 						OnRowDataBound (new GridViewRowEventArgs (bottomPagerRow));
1536 					}
1537 					if (PageCount == 1)
1538 						bottomPagerRow.Visible = false;
1539 				}
1540 			}
1541 
1542 			rows = new GridViewRowCollection (list);
1543 
1544 			if (!dataBinding)
1545 				return -1;
1546 
1547 			if (AllowPaging)
1548 				return pagedDataSource.DataSourceCount;
1549 			else
1550 				return list.Count;
1551 		}
1552 
1553 		Table ContainedTable  {
1554 			get {
1555 				if (table == null) {
1556 					table = CreateChildTable ();
1557 					Controls.Add (table);
1558 				}
1559 
1560 				return table;
1561 			}
1562 		}
1563 
CreateControlStyle()1564 		protected override Style CreateControlStyle ()
1565 		{
1566 			TableStyle style = new TableStyle (ViewState);
1567 			style.GridLines = GridLines.Both;
1568 			style.CellSpacing = 0;
1569 			return style;
1570 		}
1571 
GetRowState(int index)1572 		DataControlRowState GetRowState (int index)
1573 		{
1574 			DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
1575 			if (index == SelectedIndex)
1576 				rstate |= DataControlRowState.Selected;
1577 			if (index == EditIndex)
1578 				rstate |= DataControlRowState.Edit;
1579 			return rstate;
1580 		}
1581 
CreatePagerRow(int fieldCount, PagedDataSource dataSource)1582 		GridViewRow CreatePagerRow (int fieldCount, PagedDataSource dataSource)
1583 		{
1584 			GridViewRow row = CreateRow (-1, -1, DataControlRowType.Pager, DataControlRowState.Normal);
1585 			InitializePager (row, fieldCount, dataSource);
1586 			return row;
1587 		}
1588 
InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)1589 		protected virtual void InitializePager (GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
1590 		{
1591 			TableCell cell = new TableCell ();
1592 			if (columnSpan > 1)
1593 				cell.ColumnSpan = columnSpan;
1594 
1595 			if (pagerTemplate != null)
1596 				pagerTemplate.InstantiateIn (cell);
1597 			else
1598 				cell.Controls.Add (PagerSettings.CreatePagerControl (pagedDataSource.CurrentPageIndex, pagedDataSource.PageCount));
1599 
1600 			row.Cells.Add (cell);
1601 		}
1602 
CreateEmptyrRow(int fieldCount)1603 		GridViewRow CreateEmptyrRow (int fieldCount)
1604 		{
1605 			if (emptyDataTemplate == null && String.IsNullOrEmpty (EmptyDataText))
1606 				return null;
1607 
1608 			GridViewRow row = CreateRow (-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
1609 			TableCell cell = new TableCell ();
1610 			cell.ColumnSpan = fieldCount;
1611 
1612 			if (emptyDataTemplate != null)
1613 				emptyDataTemplate.InstantiateIn (cell);
1614 			else
1615 				cell.Text = EmptyDataText;
1616 
1617 			row.Cells.Add (cell);
1618 			return row;
1619 		}
1620 
InitializeRow(GridViewRow row, DataControlField[] fields)1621 		protected virtual void InitializeRow (GridViewRow row, DataControlField[] fields)
1622 		{
1623 			DataControlCellType ctype;
1624 			bool accessibleHeader = false;
1625 
1626 			switch (row.RowType) {
1627 				case DataControlRowType.Header:
1628 					ctype = DataControlCellType.Header;
1629 					accessibleHeader = UseAccessibleHeader;
1630 					break;
1631 				case DataControlRowType.Footer:
1632 					ctype = DataControlCellType.Footer;
1633 					break;
1634 				default:
1635 					ctype = DataControlCellType.DataCell;
1636 					break;
1637 			}
1638 
1639 			for (int n=0; n<fields.Length; n++) {
1640 				DataControlField field = fields [n];
1641 				DataControlFieldCell cell;
1642 
1643 				if (((field is BoundField) && ((BoundField)field).DataField == RowHeaderColumn) || accessibleHeader)
1644 					cell = new DataControlFieldHeaderCell (field, accessibleHeader ? TableHeaderScope.Column : TableHeaderScope.Row);
1645 				else
1646 					cell = new DataControlFieldCell (field);
1647 				row.Cells.Add (cell);
1648 				field.InitializeCell (cell, ctype, row.RowState, row.RowIndex);
1649 			}
1650 		}
1651 
LoadAndCacheProperties(string[] names, object dataItem, ref PropertyDescriptor[] cache)1652 		void LoadAndCacheProperties (string[] names, object dataItem, ref PropertyDescriptor[] cache)
1653 		{
1654 			if (cache != null)
1655 				return;
1656 
1657 			PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
1658 			int len = names != null ? names.Length : 0;
1659 			cache = new PropertyDescriptor [len];
1660 			for (int n = 0; n < len; n++) {
1661 				string propName = names [n];
1662 				PropertyDescriptor p = props.Find (propName, true);
1663 				if (p == null)
1664 					throw new InvalidOperationException ("Property '" + propName + "' not found in object of type " + dataItem.GetType ());
1665 				cache [n] = p;
1666 			}
1667 		}
1668 
CreateDictionaryFromProperties(PropertyDescriptor[] cache, object dataItem)1669 		IOrderedDictionary CreateDictionaryFromProperties (PropertyDescriptor[] cache, object dataItem)
1670 		{
1671 			OrderedDictionary dic = new OrderedDictionary ();
1672 			foreach (PropertyDescriptor p in cache)
1673 				dic [p.Name] = p.GetValue (dataItem);
1674 			return dic;
1675 		}
1676 
CreateRowDataKey(GridViewRow row)1677 		IOrderedDictionary CreateRowDataKey (GridViewRow row)
1678 		{
1679 			object dataItem = row.DataItem;
1680 			LoadAndCacheProperties (DataKeyNames, dataItem, ref cachedKeyProperties);
1681 			return CreateDictionaryFromProperties (cachedKeyProperties, dataItem);
1682 		}
CreateRowSuffixDataKey(GridViewRow row)1683 		IOrderedDictionary CreateRowSuffixDataKey (GridViewRow row)
1684 		{
1685 			object dataItem = row.DataItem;
1686 			LoadAndCacheProperties (ClientIDRowSuffix, dataItem, ref cachedSuffixKeyProperties);
1687 			return CreateDictionaryFromProperties (cachedSuffixKeyProperties, dataItem);
1688 		}
GetRowValues(GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)1689 		IOrderedDictionary GetRowValues (GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)
1690 		{
1691 			OrderedDictionary dic = new OrderedDictionary ();
1692 			ExtractRowValues (dic, row, includeReadOnlyFields, includePrimaryKey);
1693 			return dic;
1694 		}
1695 
ExtractRowValues(IOrderedDictionary fieldValues, GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)1696 		protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)
1697 		{
1698 			DataControlField field;
1699 			foreach (TableCell cell in row.Cells) {
1700 				DataControlFieldCell c = cell as DataControlFieldCell;
1701 				if (c == null)
1702 					continue;
1703 
1704 				field = c.ContainingField;
1705 				if (field != null && !field.Visible)
1706 					continue;
1707 
1708 				c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
1709 			}
1710 			if (!includePrimaryKey && DataKeyNames != null)
1711 				foreach (string key in DataKeyNames)
1712 					fieldValues.Remove (key);
1713 		}
1714 
1715 		protected override HtmlTextWriterTag TagKey {
1716 			get {
1717 				if (EnableSortingAndPagingCallbacks)
1718 					return HtmlTextWriterTag.Div;
1719 				else
1720 					return HtmlTextWriterTag.Table;
1721 			}
1722 		}
1723 
DataBind()1724 		public sealed override void DataBind ()
1725 		{
1726 			DataKeyList.Clear ();
1727 			cachedKeyProperties = null;
1728 			base.DataBind ();
1729 
1730 			keys = new DataKeyArray (DataKeyList);
1731 
1732 			GridViewRow row = HeaderRow;
1733 			if (row != null)
1734 				row.Visible = ShowHeader;
1735 
1736 			row = FooterRow;
1737 			if (row != null)
1738 				row.Visible = ShowFooter;
1739 		}
1740 
PerformDataBinding(IEnumerable data)1741 		protected internal override void PerformDataBinding (IEnumerable data)
1742 		{
1743 			base.PerformDataBinding (data);
1744 		}
1745 
PrepareControlHierarchy()1746 		protected internal virtual void PrepareControlHierarchy ()
1747 		{
1748 			if (table == null)
1749 				return;
1750 
1751 			table.Caption = Caption;
1752 			table.CaptionAlign = CaptionAlign;
1753 			table.CopyBaseAttributes (this);
1754 
1755 			foreach (GridViewRow row in table.Rows) {
1756 				switch (row.RowType) {
1757 					case DataControlRowType.Header:
1758 						if (headerStyle != null && !headerStyle.IsEmpty)
1759 							row.ControlStyle.MergeWith(headerStyle);
1760 						row.Visible = ShowHeader;
1761 						break;
1762 					case DataControlRowType.Footer:
1763 						if (footerStyle != null && !footerStyle.IsEmpty)
1764 							row.ControlStyle.MergeWith (footerStyle);
1765 						row.Visible = ShowFooter;
1766 						break;
1767 					case DataControlRowType.Pager:
1768 						if (pagerStyle != null && !pagerStyle.IsEmpty)
1769 							row.ControlStyle.MergeWith (pagerStyle);
1770 						break;
1771 					case DataControlRowType.EmptyDataRow:
1772 						if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1773 							row.ControlStyle.MergeWith (emptyDataRowStyle);
1774 						break;
1775 					case DataControlRowType.DataRow:
1776 						if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1777 							row.ControlStyle.MergeWith (editRowStyle);
1778 						if ((row.RowState & DataControlRowState.Selected) != 0 && selectedRowStyle != null && !selectedRowStyle.IsEmpty)
1779 							row.ControlStyle.MergeWith (selectedRowStyle);
1780 						if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
1781 							row.ControlStyle.MergeWith (alternatingRowStyle);
1782 						if (rowStyle != null && !rowStyle.IsEmpty)
1783 							row.ControlStyle.MergeWith (rowStyle);
1784 						break;
1785 					default:
1786 						break;
1787 				}
1788 				string sortExpression = SortExpression;
1789 				bool haveSorting = !String.IsNullOrEmpty (sortExpression);
1790 				foreach (TableCell cell in row.Cells) {
1791 					DataControlFieldCell fcell = cell as DataControlFieldCell;
1792 					if (fcell != null) {
1793 						DataControlField field = fcell.ContainingField;
1794 						if (field == null)
1795 							continue;
1796 						if (!field.Visible) {
1797 							cell.Visible = false;
1798 							continue;
1799 						}
1800 
1801 						switch (row.RowType) {
1802 							case DataControlRowType.Header:
1803 								if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
1804 									cell.ControlStyle.MergeWith (field.HeaderStyle);
1805 								if (haveSorting)
1806 									MergeWithSortingStyle (sortExpression, sortedAscendingHeaderStyle, sortedDescendingHeaderStyle, field, cell);
1807 								break;
1808 							case DataControlRowType.Footer:
1809 								if (field.FooterStyleCreated && !field.FooterStyle.IsEmpty)
1810 									cell.ControlStyle.MergeWith (field.FooterStyle);
1811 								break;
1812 							default:
1813 								if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty) {
1814 									foreach (Control c in cell.Controls) {
1815 										WebControl wc = c as WebControl;
1816 										if (wc != null)
1817 											wc.ControlStyle.MergeWith (field.ControlStyle);
1818 									}
1819 								}
1820 								if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
1821 									cell.ControlStyle.MergeWith (field.ItemStyle);
1822 								if (haveSorting)
1823 									MergeWithSortingStyle (sortExpression, sortedAscendingCellStyle, sortedDescendingCellStyle, field, cell);
1824 								break;
1825 						}
1826 					}
1827 				}
1828 			}
1829 		}
MergeWithSortingStyle(string sortExpression, TableItemStyle ascending, TableItemStyle descending, DataControlField field, TableCell cell)1830 		void MergeWithSortingStyle (string sortExpression, TableItemStyle ascending, TableItemStyle descending, DataControlField field, TableCell cell)
1831 		{
1832 			if (String.Compare (field.SortExpression, sortExpression, StringComparison.OrdinalIgnoreCase) != 0)
1833 				return;
1834 
1835 			cell.ControlStyle.MergeWith (SortDirection == SortDirection.Ascending ? ascending : descending);
1836 		}
OnInit(EventArgs e)1837 		protected internal override void OnInit (EventArgs e)
1838 		{
1839 			Page page = Page;
1840 			if (page != null)
1841 				page.RegisterRequiresControlState (this);
1842 			base.OnInit (e);
1843 		}
1844 
OnFieldsChanged(object sender, EventArgs args)1845 		void OnFieldsChanged (object sender, EventArgs args)
1846 		{
1847 			RequireBinding ();
1848 		}
1849 
OnDataPropertyChanged()1850 		protected override void OnDataPropertyChanged ()
1851 		{
1852 			base.OnDataPropertyChanged ();
1853 			RequireBinding ();
1854 		}
1855 
OnDataSourceViewChanged(object sender, EventArgs e)1856 		protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1857 		{
1858 			base.OnDataSourceViewChanged (sender, e);
1859 			RequireBinding ();
1860 		}
1861 
OnBubbleEvent(object source, EventArgs e)1862 		protected override bool OnBubbleEvent (object source, EventArgs e)
1863 		{
1864 			GridViewCommandEventArgs args = e as GridViewCommandEventArgs;
1865 			if (args != null) {
1866 				bool causesValidation = false;
1867 				IButtonControl button = args.CommandSource as IButtonControl;
1868 				if (button != null && button.CausesValidation) {
1869 					Page.Validate (button.ValidationGroup);
1870 					causesValidation = true;
1871 				}
1872 				OnRowCommand (args);
1873 				string param = args.CommandArgument as string;
1874 				if (param == null || param.Length == 0) {
1875 					GridViewRow row = args.Row;
1876 					if (row != null)
1877 						param = row.RowIndex.ToString();
1878 				}
1879 				ProcessEvent (args.CommandName, param, causesValidation);
1880 				return true;
1881 			}
1882 			return base.OnBubbleEvent (source, e);
1883 		}
1884 
IPostBackEventHandler.RaisePostBackEvent(string eventArgument)1885 		void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1886 		{
1887 			ValidateEvent (UniqueID, eventArgument);
1888 			RaisePostBackEvent (eventArgument);
1889 		}
1890 
1891 		// This is prolly obsolete
RaisePostBackEvent(string eventArgument)1892 		protected virtual void RaisePostBackEvent (string eventArgument)
1893 		{
1894 			GridViewCommandEventArgs args;
1895 			int i = eventArgument.IndexOf ('$');
1896 			if (i != -1)
1897 				args = new GridViewCommandEventArgs (this, new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1)));
1898 			else
1899 				args = new GridViewCommandEventArgs (this, new CommandEventArgs (eventArgument, null));
1900 
1901 			OnRowCommand (args);
1902 			ProcessEvent (args.CommandName, (string) args.CommandArgument, false);
1903 		}
1904 
ProcessEvent(string eventName, string param, bool causesValidation)1905 		void ProcessEvent (string eventName, string param, bool causesValidation)
1906 		{
1907 			switch (eventName) {
1908 				case DataControlCommands.PageCommandName:
1909 					int newIndex = -1;
1910 					switch (param) {
1911 						case DataControlCommands.FirstPageCommandArgument:
1912 							newIndex = 0;
1913 							break;
1914 						case DataControlCommands.LastPageCommandArgument:
1915 							newIndex = PageCount - 1;
1916 							break;
1917 						case DataControlCommands.NextPageCommandArgument:
1918 							newIndex = PageIndex + 1;
1919 							break;
1920 						case DataControlCommands.PreviousPageCommandArgument:
1921 							newIndex = PageIndex - 1;
1922 							break;
1923 						default:
1924 							int paramIndex = 0;
1925 							int.TryParse (param, out paramIndex);
1926 							newIndex = paramIndex - 1;
1927 							break;
1928 					}
1929 					SetPageIndex (newIndex);
1930 					break;
1931 
1932 				case DataControlCommands.FirstPageCommandArgument:
1933 					SetPageIndex (0);
1934 					break;
1935 
1936 				case DataControlCommands.LastPageCommandArgument:
1937 					SetPageIndex (PageCount - 1);
1938 					break;
1939 
1940 				case DataControlCommands.NextPageCommandArgument:
1941 					if (PageIndex < PageCount - 1)
1942 						SetPageIndex (PageIndex + 1);
1943 					break;
1944 
1945 				case DataControlCommands.PreviousPageCommandArgument:
1946 					if (PageIndex > 0)
1947 						SetPageIndex (PageIndex - 1);
1948 					break;
1949 
1950 				case DataControlCommands.SelectCommandName:
1951 					SelectRow (int.Parse (param));
1952 					break;
1953 
1954 				case DataControlCommands.EditCommandName:
1955 					SetEditRow (int.Parse (param));
1956 					break;
1957 
1958 				case DataControlCommands.UpdateCommandName:
1959 					int editIndex = int.Parse (param);
1960 					UpdateRow (Rows [editIndex], editIndex, causesValidation);
1961 					break;
1962 
1963 				case DataControlCommands.CancelCommandName:
1964 					CancelEdit ();
1965 					break;
1966 
1967 				case DataControlCommands.DeleteCommandName:
1968 					DeleteRow (int.Parse (param));
1969 					break;
1970 
1971 				case DataControlCommands.SortCommandName:
1972 					Sort (param);
1973 					break;
1974 			}
1975 		}
1976 
Sort(string newSortExpression)1977 		void Sort (string newSortExpression)
1978 		{
1979 			SortDirection newDirection = SortDirection.Ascending;
1980 			if (sortExpression == newSortExpression && sortDirection == SortDirection.Ascending)
1981 				newDirection = SortDirection.Descending;
1982 
1983 			Sort (newSortExpression, newDirection);
1984 		}
1985 
Sort(string sortExpression, SortDirection sortDirection)1986 		public virtual void Sort (string sortExpression, SortDirection sortDirection)
1987 		{
1988 			GridViewSortEventArgs args = new GridViewSortEventArgs (sortExpression, sortDirection);
1989 			OnSorting (args);
1990 			if (args.Cancel)
1991 				return;
1992 
1993 			if (IsBoundUsingDataSourceID) {
1994 				EditIndex = -1;
1995 				PageIndex = 0;
1996 				SortExpression = args.SortExpression;
1997 				SortDirection = args.SortDirection;
1998 			}
1999 
2000 			OnSorted (EventArgs.Empty);
2001 		}
2002 		public
SelectRow(int rowIndex)2003 		void SelectRow (int rowIndex)
2004 		{
2005 			GridViewSelectEventArgs args = new GridViewSelectEventArgs (rowIndex);
2006 			OnSelectedIndexChanging (args);
2007 			if (!args.Cancel) {
2008 				RequireBinding ();
2009 				SelectedIndex = args.NewSelectedIndex;
2010 				OnSelectedIndexChanged (EventArgs.Empty);
2011 			}
2012 		}
2013 		public
SetPageIndex(int rowIndex)2014 		void SetPageIndex (int rowIndex)
2015 		{
2016 			GridViewPageEventArgs args = new GridViewPageEventArgs (rowIndex);
2017 			OnPageIndexChanging (args);
2018 
2019 			if (args.Cancel || !IsBoundUsingDataSourceID)
2020 				return;
2021 
2022 			EndRowEdit ();
2023 			PageIndex = args.NewPageIndex;
2024 			OnPageIndexChanged (EventArgs.Empty);
2025 		}
2026 		public
SetEditRow(int rowIndex)2027 		void SetEditRow (int rowIndex)
2028 		{
2029 			GridViewEditEventArgs args = new GridViewEditEventArgs (rowIndex);
2030 			OnRowEditing (args);
2031 
2032 			if (args.Cancel || !IsBoundUsingDataSourceID)
2033 				return;
2034 
2035 			EditIndex = args.NewEditIndex;
2036 		}
2037 
CancelEdit()2038 		void CancelEdit ()
2039 		{
2040 			GridViewCancelEditEventArgs args = new GridViewCancelEditEventArgs (EditIndex);
2041 			OnRowCancelingEdit (args);
2042 
2043 			if (args.Cancel || !IsBoundUsingDataSourceID)
2044 				return;
2045 
2046 			EndRowEdit ();
2047 		}
2048 
2049 		[MonoTODO ("Support two-way binding expressions")]
UpdateRow(int rowIndex, bool causesValidation)2050 		public virtual void UpdateRow (int rowIndex, bool causesValidation)
2051 		{
2052 			if (rowIndex != EditIndex)
2053 				throw new NotSupportedException ();
2054 
2055 			GridViewRow row = Rows [rowIndex];
2056 			UpdateRow (row, rowIndex, causesValidation);
2057 		}
2058 
UpdateRow(GridViewRow row, int rowIndex, bool causesValidation)2059 		void UpdateRow (GridViewRow row, int rowIndex, bool causesValidation)
2060 		{
2061 			if (causesValidation && Page != null && !Page.IsValid)
2062 				return;
2063 
2064 			currentEditOldValues = CopyOrderedDictionary (OldEditValues.Values);
2065 			currentEditRowKeys = CopyOrderedDictionary (DataKeys [rowIndex].Values);
2066 			currentEditNewValues = GetRowValues (row, false, false);
2067 
2068 			GridViewUpdateEventArgs args = new GridViewUpdateEventArgs (rowIndex, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
2069 			OnRowUpdating (args);
2070 
2071 			if (args.Cancel || !IsBoundUsingDataSourceID)
2072 				return;
2073 
2074 			DataSourceView view = GetData ();
2075 			if (view == null)
2076 				throw new HttpException ("The DataSourceView associated to data bound control was null");
2077 			view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
2078 		}
2079 
CopyOrderedDictionary(IOrderedDictionary sourceDic)2080 		static IOrderedDictionary CopyOrderedDictionary (IOrderedDictionary sourceDic)
2081 		{
2082 			OrderedDictionary copyDic = new OrderedDictionary ();
2083 			foreach (object key in sourceDic.Keys)
2084 				copyDic.Add (key, sourceDic [key]);
2085 			return copyDic;
2086 		}
2087 
UpdateCallback(int recordsAffected, Exception exception)2088 		bool UpdateCallback (int recordsAffected, Exception exception)
2089 		{
2090 			GridViewUpdatedEventArgs dargs = new GridViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
2091 			OnRowUpdated (dargs);
2092 
2093 			if (!dargs.KeepInEditMode)
2094 				EndRowEdit ();
2095 
2096 			return dargs.ExceptionHandled;
2097 		}
2098 
DeleteRow(int rowIndex)2099 		public virtual void DeleteRow (int rowIndex)
2100 		{
2101 			GridViewRow row = Rows [rowIndex];
2102 			currentEditRowKeys = CopyOrderedDictionary (DataKeys [rowIndex].Values);
2103 			currentEditNewValues = GetRowValues (row, true, true);
2104 
2105 			GridViewDeleteEventArgs args = new GridViewDeleteEventArgs (rowIndex, currentEditRowKeys, currentEditNewValues);
2106 			OnRowDeleting (args);
2107 
2108 			if (args.Cancel || !IsBoundUsingDataSourceID)
2109 				return;
2110 
2111 			RequireBinding ();
2112 			DataSourceView view = GetData ();
2113 			if (view != null)
2114 				view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
2115 			else {
2116 				GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
2117 				OnRowDeleted (dargs);
2118 			}
2119 		}
2120 
DeleteCallback(int recordsAffected, Exception exception)2121 		bool DeleteCallback (int recordsAffected, Exception exception)
2122 		{
2123 			GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
2124 			OnRowDeleted (dargs);
2125 			return dargs.ExceptionHandled;
2126 		}
2127 
EndRowEdit()2128 		void EndRowEdit ()
2129 		{
2130 			EditIndex = -1;
2131 			oldEditValues = new DataKey (new OrderedDictionary ());
2132 			currentEditRowKeys = null;
2133 			currentEditOldValues = null;
2134 			currentEditNewValues = null;
2135 		}
2136 
LoadControlState(object savedState)2137 		protected internal override void LoadControlState (object savedState)
2138 		{
2139 			if (savedState == null)
2140 				return;
2141 			object[] state = (object[]) savedState;
2142 			base.LoadControlState (state[0]);
2143 			pageIndex = (int) state[1];
2144 			selectedIndex = (int) state[2];
2145 			editIndex = (int) state[3];
2146 			sortExpression = (string) state[4];
2147 			sortDirection = (SortDirection) state[5];
2148 			DataKeyNames = (string []) state [6];
2149 			if (state [7] != null)
2150 				LoadDataKeyArrayState ((object []) state [7], out keys);
2151 			if (state [8] != null)
2152 				((IStateManager) OldEditValues).LoadViewState (state [8]);
2153 			pageCount = (int)state [9];
2154 			if (state [10] != null)
2155 				ClientIDRowSuffix = (string[]) state [10];
2156 			if (state [11] != null)
2157 				LoadDataKeyArrayState ((object []) state [11], out rowSuffixKeys);
2158 		}
2159 
SaveControlState()2160 		protected internal override object SaveControlState ()
2161 		{
2162 			if (EnableSortingAndPagingCallbacks) {
2163 				Page page = Page;
2164 				ClientScriptManager scriptManager = page != null ? page.ClientScript : null;
2165 
2166 				if (scriptManager != null) {
2167 					scriptManager.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
2168 					scriptManager.RegisterHiddenField (ClientID + "_SortExpression", SortExpression);
2169 					scriptManager.RegisterHiddenField (ClientID + "_SortDirection", ((int)SortDirection).ToString());
2170 				}
2171 			}
2172 
2173 			object bstate = base.SaveControlState ();
2174 			return new object [] {
2175 				bstate,
2176 				pageIndex,
2177 				selectedIndex,
2178 				editIndex,
2179 				sortExpression,
2180 				sortDirection,
2181 				DataKeyNames,
2182 				SaveDataKeyArrayState (keys),
2183 				(oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState ()),
2184 				pageCount,
2185 				ClientIDRowSuffix,
2186 				SaveDataKeyArrayState (rowSuffixKeys)
2187 			};
2188 		}
2189 
SaveDataKeyArrayState(DataKeyArray keys)2190 		object [] SaveDataKeyArrayState (DataKeyArray keys)
2191 		{
2192 			if (keys == null)
2193 				return null;
2194 
2195 			object [] state = new object [keys.Count];
2196 			for (int i = 0; i < keys.Count; i++)
2197 				state [i] = ((IStateManager) keys [i]).SaveViewState ();
2198 			return state;
2199 		}
2200 
LoadDataKeyArrayState(object [] state, out DataKeyArray keys)2201 		void LoadDataKeyArrayState (object [] state, out DataKeyArray keys)
2202 		{
2203 			List <DataKey> dataKeyList = DataKeyList;
2204 			string[] dataKeyNames = DataKeyNames;
2205 			int dataKeyNamesLen = dataKeyNames.Length;
2206 
2207 			for (int i = 0; i < state.Length; i++) {
2208 				DataKey dataKey = new DataKey (new OrderedDictionary (dataKeyNamesLen), dataKeyNames);
2209 				((IStateManager) dataKey).LoadViewState (state [i]);
2210 				dataKeyList.Add (dataKey);
2211 			}
2212 			keys = new DataKeyArray (dataKeyList);
2213 		}
2214 
TrackViewState()2215 		protected override void TrackViewState ()
2216 		{
2217 			base.TrackViewState();
2218 			if (columns != null)
2219 				((IStateManager)columns).TrackViewState();
2220 			if (pagerSettings != null)
2221 				((IStateManager)pagerSettings).TrackViewState();
2222 			if (alternatingRowStyle != null)
2223 				((IStateManager)alternatingRowStyle).TrackViewState();
2224 			if (footerStyle != null)
2225 				((IStateManager)footerStyle).TrackViewState();
2226 			if (headerStyle != null)
2227 				((IStateManager)headerStyle).TrackViewState();
2228 			if (pagerStyle != null)
2229 				((IStateManager)pagerStyle).TrackViewState();
2230 			if (rowStyle != null)
2231 				((IStateManager)rowStyle).TrackViewState();
2232 			if (selectedRowStyle != null)
2233 				((IStateManager)selectedRowStyle).TrackViewState();
2234 			if (editRowStyle != null)
2235 				((IStateManager)editRowStyle).TrackViewState();
2236 			if (emptyDataRowStyle != null)
2237 				((IStateManager)emptyDataRowStyle).TrackViewState();
2238 			if (sortedAscendingCellStyle != null)
2239 				((IStateManager)sortedAscendingCellStyle).TrackViewState ();
2240 
2241 			if (sortedAscendingHeaderStyle != null)
2242 				((IStateManager)sortedAscendingHeaderStyle).TrackViewState ();
2243 
2244 			if (sortedDescendingCellStyle != null)
2245 				((IStateManager)sortedDescendingCellStyle).TrackViewState ();
2246 
2247 			if (sortedDescendingHeaderStyle != null)
2248 				((IStateManager)sortedDescendingHeaderStyle).TrackViewState ();
2249 			if (rowSuffixKeys != null)
2250 				((IStateManager) rowSuffixKeys).TrackViewState ();
2251 			if (keys != null)
2252 				((IStateManager)keys).TrackViewState();
2253 			if (autoFieldProperties != null) {
2254 				foreach (IStateManager sm in autoFieldProperties)
2255 					sm.TrackViewState ();
2256 			}
2257 		}
2258 
SaveViewState()2259 		protected override object SaveViewState ()
2260 		{
2261 			object[] autoFieldsData = null;
2262 
2263 			if (autoFieldProperties != null) {
2264 				object[] data = new object [autoFieldProperties.Length];
2265 				bool allNull = true;
2266 				for (int n = 0; n < data.Length; n++) {
2267 					data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
2268 					if (data [n] != null)
2269 						allNull = false;
2270 				}
2271 				if (!allNull)
2272 					autoFieldsData = data;
2273 			}
2274 
2275 			object[] states = {
2276 				base.SaveViewState(), // 0
2277 				(columns == null ? null : ((IStateManager)columns).SaveViewState()), // 1
2278 				(pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState()), // 2
2279 				(alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState()), // 3
2280 				(footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState()), // 4
2281 				(headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState()), // 5
2282 				(pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState()), // 6
2283 				(rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState()), // 7
2284 				(selectedRowStyle == null ? null : ((IStateManager)selectedRowStyle).SaveViewState()), // 8
2285 				(editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState()), // 9
2286 				(emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState()), // 10
2287 				autoFieldsData, // 11
2288 				sortedAscendingCellStyle == null ? null : ((IStateManager)sortedAscendingCellStyle).SaveViewState (), // 12
2289 				sortedAscendingHeaderStyle == null ? null : ((IStateManager)sortedAscendingHeaderStyle).SaveViewState (), // 13
2290 				sortedDescendingCellStyle == null ? null : ((IStateManager)sortedDescendingCellStyle).SaveViewState (), // 14
2291 				sortedDescendingHeaderStyle == null ? null : ((IStateManager)sortedDescendingHeaderStyle).SaveViewState () // 15
2292 			};
2293 
2294 			for (int i = states.Length - 1; i >= 0; i--) {
2295 				if (states [i] != null)
2296 					return states;
2297 			}
2298 
2299 			return null;
2300 		}
2301 
LoadViewState(object savedState)2302 		protected override void LoadViewState (object savedState)
2303 		{
2304 			if (savedState == null) {
2305 				base.LoadViewState (null);
2306 				return;
2307 			}
2308 
2309 			object [] states = (object []) savedState;
2310 
2311 			if (states[11] != null) {
2312 				object[] data = (object[]) states [11];
2313 				autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
2314 				for (int n=0; n<data.Length; n++) {
2315 					IStateManager p = new AutoGeneratedFieldProperties ();
2316 					p.TrackViewState ();
2317 					p.LoadViewState (data [n]);
2318 					autoFieldProperties [n] = (AutoGeneratedFieldProperties) p;
2319 				}
2320 			}
2321 
2322 			base.LoadViewState (states[0]);
2323 
2324 			if (states[1] != null)
2325 				((IStateManager)Columns).LoadViewState (states[1]);
2326 			if (states[2] != null)
2327 				((IStateManager)PagerSettings).LoadViewState (states[2]);
2328 			if (states[3] != null)
2329 				((IStateManager)AlternatingRowStyle).LoadViewState (states[3]);
2330 			if (states[4] != null)
2331 				((IStateManager)FooterStyle).LoadViewState (states[4]);
2332 			if (states[5] != null)
2333 				((IStateManager)HeaderStyle).LoadViewState (states[5]);
2334 			if (states[6] != null)
2335 				((IStateManager)PagerStyle).LoadViewState (states[6]);
2336 			if (states[7] != null)
2337 				((IStateManager)RowStyle).LoadViewState (states[7]);
2338 			if (states[8] != null)
2339 				((IStateManager)SelectedRowStyle).LoadViewState (states[8]);
2340 			if (states[9] != null)
2341 				((IStateManager)EditRowStyle).LoadViewState (states[9]);
2342 			if (states[10] != null)
2343 				((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
2344 			if (states [12] != null)
2345 				((IStateManager)sortedAscendingCellStyle).LoadViewState (states [12]);
2346 			if (states [13] != null)
2347 				((IStateManager)sortedAscendingHeaderStyle).LoadViewState (states [13]);
2348 			if (states [14] != null)
2349 				((IStateManager)sortedDescendingCellStyle).LoadViewState (states [14]);
2350 			if (states [15] != null)
2351 				((IStateManager)sortedDescendingHeaderStyle).LoadViewState (states [15]);
2352 		}
2353 
ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)2354 		void ICallbackEventHandler.RaiseCallbackEvent (string eventArgument)
2355 		{
2356 			RaiseCallbackEvent (eventArgument);
2357 		}
2358 
RaiseCallbackEvent(string eventArgument)2359 		protected virtual void RaiseCallbackEvent (string eventArgument)
2360 		{
2361 			string[] clientData = eventArgument.Split ('|');
2362 			PageIndex = int.Parse (clientData[0]);
2363 			SortExpression = HttpUtility.UrlDecode (clientData [1]);
2364 			SortDirection = (SortDirection) int.Parse (clientData [2]);
2365 
2366 			RaisePostBackEvent (clientData[3]);
2367 			DataBind ();
2368 		}
2369 
ICallbackEventHandler.GetCallbackResult()2370 		string ICallbackEventHandler.GetCallbackResult ()
2371 		{
2372 			return GetCallbackResult ();
2373 		}
2374 
GetCallbackResult()2375 		protected virtual string GetCallbackResult ()
2376 		{
2377 			PrepareControlHierarchy ();
2378 
2379 			StringWriter sw = new StringWriter ();
2380 			sw.Write (PageIndex.ToString () + '|' + SortExpression + '|' + (int) SortDirection + '|');
2381 
2382 			HtmlTextWriter writer = new HtmlTextWriter (sw);
2383 			RenderGrid (writer);
2384 			return sw.ToString ();
2385 		}
2386 
ICallbackContainer.GetCallbackScript(IButtonControl buttonControl, string argument)2387 		string ICallbackContainer.GetCallbackScript (IButtonControl buttonControl, string argument)
2388 		{
2389 			return GetCallbackScript (buttonControl, argument);
2390 		}
2391 
GetCallbackScript(IButtonControl buttonControl, string argument)2392 		protected virtual string GetCallbackScript (IButtonControl buttonControl, string argument)
2393 		{
2394 			if (EnableSortingAndPagingCallbacks) {
2395 				Page page = Page;
2396 				if (page != null)
2397 					page.ClientScript.RegisterForEventValidation (UniqueID, argument);
2398 				return "javascript:GridView_ClientEvent (\"" + ClientID + "\",\"" + buttonControl.CommandName + "$" + buttonControl.CommandArgument + "\"); return false;";
2399 			} else
2400 				return null;
2401 		}
2402 
OnPagePreLoad(object sender, EventArgs e)2403 		protected override void OnPagePreLoad (object sender, EventArgs e)
2404 		{
2405 			base.OnPagePreLoad (sender, e);
2406 			Page page = Page;
2407 
2408 			if (page != null && page.IsPostBack && EnableSortingAndPagingCallbacks) {
2409 				HttpRequest req = page.Request;
2410 				int value;
2411 				if (req != null) {
2412 					if (int.TryParse (req.Form [ClientID + "_Page"], out value))
2413 						PageIndex = value;
2414 
2415 					if (int.TryParse (req.Form [ClientID + "_SortDirection"], out value))
2416 						SortDirection = (SortDirection) value;
2417 					SortExpression = req.Form [ClientID + "_SortExpression"];
2418 				}
2419 			}
2420 		}
2421 
2422 		const string onPreRenderScript = @"var {0} = new Object ();
2423 {0}.pageIndex = {1};
2424 {0}.sortExp = {2};
2425 {0}.sortDir = {3};
2426 {0}.uid = {4};
2427 {0}.form = {5};
2428 ";
OnPreRender(EventArgs e)2429 		protected internal override void OnPreRender (EventArgs e)
2430 		{
2431 			base.OnPreRender (e);
2432 
2433 			if (EnableSortingAndPagingCallbacks) {
2434 				Page page = Page;
2435 				ClientScriptManager scriptManager = page != null ? page.ClientScript : null;
2436 				if (scriptManager != null) {
2437 					if (!scriptManager.IsClientScriptIncludeRegistered (typeof(GridView), "GridView.js")) {
2438 						string url = scriptManager.GetWebResourceUrl (typeof(GridView), "GridView.js");
2439 						scriptManager.RegisterClientScriptInclude (typeof(GridView), "GridView.js", url);
2440 					}
2441 
2442 					string cgrid = ClientID + "_data";
2443 					string script = String.Format (onPreRenderScript,
2444 								       cgrid,
2445 								       ClientScriptManager.GetScriptLiteral (PageIndex),
2446 								       ClientScriptManager.GetScriptLiteral (SortExpression == null ? String.Empty : SortExpression),
2447 								       ClientScriptManager.GetScriptLiteral ((int) SortDirection),
2448 								       ClientScriptManager.GetScriptLiteral (UniqueID),
2449 								       page.theForm);
2450 
2451 					scriptManager.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
2452 
2453 					// Make sure the basic script infrastructure is rendered
2454 					scriptManager.GetCallbackEventReference (this, "null", String.Empty, "null");
2455 					scriptManager.GetPostBackClientHyperlink (this, String.Empty);
2456 				}
2457 			}
2458 		}
2459 
Render(HtmlTextWriter writer)2460 		protected internal override void Render (HtmlTextWriter writer)
2461 		{
2462 			PrepareControlHierarchy ();
2463 			if (EnableSortingAndPagingCallbacks)
2464 				writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
2465 			writer.RenderBeginTag (HtmlTextWriterTag.Div);
2466 
2467 			RenderGrid (writer);
2468 
2469 			writer.RenderEndTag ();
2470 		}
2471 
RenderGrid(HtmlTextWriter writer)2472 		void RenderGrid (HtmlTextWriter writer)
2473 		{
2474 			if (table == null)
2475 				return;
2476 
2477 			table.Render (writer);
2478 		}
2479 
IPostBackContainer.GetPostBackOptions(IButtonControl control)2480 		PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
2481 		{
2482 			if (control == null)
2483 				throw new ArgumentNullException ("control");
2484 
2485 			if (control.CausesValidation)
2486 				throw new InvalidOperationException ("A button that causes validation in GridView '" + 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.");
2487 
2488 			PostBackOptions options = new PostBackOptions (this);
2489 			options.Argument = control.CommandName + "$" + control.CommandArgument;
2490 			options.RequiresJavaScriptProtocol = true;
2491 
2492 			return options;
2493 		}
2494 	}
2495 }
2496