1 //------------------------------------------------------------------------------
2 // <copyright file="WebPartZoneBase.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 
7 namespace System.Web.UI.WebControls.WebParts {
8 
9     using System;
10     using System.Collections;
11     using System.ComponentModel;
12     using System.Drawing;
13     using System.Drawing.Design;
14     using System.Globalization;
15     using System.Web.Security;
16     using System.Web;
17     using System.Web.UI;
18     using System.Web.UI.WebControls;
19     using System.Web.Util;
20 
21     /// <devdoc>
22     /// Base class for all zone classes that host WebPart controls.  Inherits from Zone, adding client-side
23     /// dragging, verbs, and additional styles.  Zones that are database driven should inherit from
24     /// this class.
25     /// </devdoc>
26     [
27     Designer("System.Web.UI.Design.WebControls.WebParts.WebPartZoneBaseDesigner, " + AssemblyRef.SystemDesign),
28     ]
29     public abstract class WebPartZoneBase : WebZone, IPostBackEventHandler, IWebPartMenuUser {
30 
31         private static readonly object CreateVerbsEvent = new object();
32 
33         internal const string EventArgumentSeparator = ":";
34         private const char eventArgumentSeparatorChar = ':';
35 
36         private const string dragEventArgument = "Drag";
37         private const string partVerbEventArgument = "partverb";
38         private const string zoneVerbEventArgument = "zoneverb";
39         private const string closeEventArgument = "close";
40         private const string connectEventArgument = "connect";
41         private const string deleteEventArgument = "delete";
42         private const string editEventArgument = "edit";
43         private const string minimizeEventArgument = "minimize";
44         private const string restoreEventArgument = "restore";
45 
46         // PERF: concat the event arg with the separator at compile-time
47         private const string partVerbEventArgumentWithSeparator = partVerbEventArgument + EventArgumentSeparator;
48         private const string zoneVerbEventArgumentWithSeparator = zoneVerbEventArgument + EventArgumentSeparator;
49         private const string connectEventArgumentWithSeparator = connectEventArgument + EventArgumentSeparator;
50         private const string editEventArgumentWithSeparator = editEventArgument + EventArgumentSeparator;
51         private const string minimizeEventArgumentWithSeparator = minimizeEventArgument + EventArgumentSeparator;
52         private const string restoreEventArgumentWithSeparator = restoreEventArgument + EventArgumentSeparator;
53         private const string closeEventArgumentWithSeparator = closeEventArgument + EventArgumentSeparator;
54         private const string deleteEventArgumentWithSeparator = deleteEventArgument + EventArgumentSeparator;
55 
56         // Indexes into the ViewState array
57         private const int baseIndex = 0;
58         private const int selectedPartChromeStyleIndex = 1;
59         private const int closeVerbIndex = 2;
60         private const int connectVerbIndex = 3;
61         private const int deleteVerbIndex = 4;
62         private const int editVerbIndex = 5;
63         private const int helpVerbIndex = 6;
64         private const int minimizeVerbIndex = 7;
65         private const int restoreVerbIndex = 8;
66         private const int exportVerbIndex = 9;
67         private const int menuPopupStyleIndex = 10;
68         private const int menuLabelStyleIndex = 11;
69         private const int menuLabelHoverStyleIndex = 12;
70         private const int menuCheckImageStyleIndex = 13;
71         private const int menuVerbStyleIndex = 14;
72         private const int menuVerbHoverStyleIndex = 15;
73         private const int controlStyleIndex = 16;
74         private const int titleBarVerbStyleIndex = 17;
75         private const int viewStateArrayLength = 18;
76 
77         private Style _selectedPartChromeStyle;
78         private WebPartVerb _closeVerb;
79         private WebPartVerb _connectVerb;
80         private WebPartVerb _deleteVerb;
81         private WebPartVerb _editVerb;
82         private WebPartVerb _exportVerb;
83         private WebPartVerb _helpVerb;
84         private WebPartVerb _minimizeVerb;
85         private WebPartVerb _restoreVerb;
86 
87         private WebPartVerbCollection _verbs;
88         private WebPartMenuStyle _menuPopupStyle;
89         private Style _menuLabelStyle;
90         private Style _menuLabelHoverStyle;
91         private Style _menuCheckImageStyle;
92         private Style _menuVerbHoverStyle;
93         private Style _menuVerbStyle;
94         private Style _titleBarVerbStyle;
95 
96         private Color _borderColor;
97         private BorderStyle _borderStyle;
98         private Unit _borderWidth;
99 
100         private WebPartChrome _webPartChrome;
101         private WebPartMenu _menu;
102 
103         [
104         DefaultValue(true),
105         Themeable(false),
106         WebCategory("Behavior"),
107         WebSysDescription(SR.WebPartZoneBase_AllowLayoutChange),
108         ]
109         public virtual bool AllowLayoutChange {
110             get {
111                 object b = ViewState["AllowLayoutChange"];
112                 return (b != null) ? (bool)b : true;
113             }
114             set {
115                 ViewState["AllowLayoutChange"] = value;
116             }
117         }
118 
119         /// <devdoc>
120         /// Overridden to change default value.
121         /// </devdoc>
122         [
123         DefaultValue(typeof(Color), "Gray"),
124         ]
125         public override Color BorderColor {
126             get {
127                 if (ControlStyleCreated == false) {
128                     return Color.Gray;
129                 }
130                 return base.BorderColor;
131             }
132             set {
133                 base.BorderColor = value;
134             }
135         }
136 
137         /// <devdoc>
138         /// Overridden to change default value.
139         /// </devdoc>
140         [
141         DefaultValue(BorderStyle.Solid)
142         ]
143         public override BorderStyle BorderStyle {
144             get {
145                 if (ControlStyleCreated == false) {
146                     return BorderStyle.Solid;
147                 }
148                 return base.BorderStyle;
149             }
150             set {
151                 base.BorderStyle = value;
152             }
153         }
154 
155         /// <devdoc>
156         /// Overridden to change default value.
157         /// </devdoc>
158         [
159         DefaultValue(typeof(Unit), "1")
160         ]
161         public override Unit BorderWidth {
162             get {
163                 if (ControlStyleCreated == false) {
164                     return 1;
165                 }
166                 return base.BorderWidth;
167             }
168             set {
169                 base.BorderWidth = value;
170             }
171         }
172 
173         [
174         DefaultValue(null),
175         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
176         NotifyParentProperty(true),
177         PersistenceMode(PersistenceMode.InnerProperty),
178         WebCategory("Verbs"),
179         WebSysDescription(SR.WebPartZoneBase_CloseVerb),
180         ]
181         public virtual WebPartVerb CloseVerb {
182             get {
183                 if (_closeVerb == null) {
184                     _closeVerb = new WebPartCloseVerb();
185                     if (IsTrackingViewState) {
186                         ((IStateManager)_closeVerb).TrackViewState();
187                     }
188                 }
189                 return _closeVerb;
190             }
191         }
192 
193         [
194         DefaultValue(null),
195         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
196         NotifyParentProperty(true),
197         PersistenceMode(PersistenceMode.InnerProperty),
198         WebCategory("Verbs"),
199         WebSysDescription(SR.WebPartZoneBase_ConnectVerb),
200         ]
201         public virtual WebPartVerb ConnectVerb {
202             get {
203                 if (_connectVerb == null) {
204                     _connectVerb = new WebPartConnectVerb();
205                     if (IsTrackingViewState) {
206                         ((IStateManager)_connectVerb).TrackViewState();
207                     }
208                 }
209                 return _connectVerb;
210             }
211         }
212 
213         [
214         DefaultValue(null),
215         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
216         NotifyParentProperty(true),
217         PersistenceMode(PersistenceMode.InnerProperty),
218         WebCategory("Verbs"),
219         WebSysDescription(SR.WebPartZoneBase_DeleteVerb),
220         ]
221         public virtual WebPartVerb DeleteVerb {
222             get {
223                 if (_deleteVerb == null) {
224                     _deleteVerb = new WebPartDeleteVerb();
225                     if (IsTrackingViewState) {
226                         ((IStateManager)_deleteVerb).TrackViewState();
227                     }
228                 }
229                 return _deleteVerb;
230             }
231         }
232 
233         /// <devdoc>
234         /// The string displayed to identify the zone.
235         /// </devdoc>
236         [
237         Browsable(false),
238         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
239         ]
240         public virtual string DisplayTitle {
241             get {
242                 string title = HeaderText;
243                 if (!String.IsNullOrEmpty(title)) {
244                     return title;
245                 }
246 
247                 string id = ID;
248                 if (!String.IsNullOrEmpty(id)) {
249                     return id;
250                 }
251 
252                 // ID is required to be set by WebPartManager.RegisterZone but this is still a good fallback.
253                 int index = 1;
254                 if (WebPartManager != null) {
255                     index = WebPartManager.Zones.IndexOf(this) + 1;
256                 }
257                 return SR.GetString(SR.WebPartZoneBase_DisplayTitleFallback,
258                                                         index.ToString(CultureInfo.CurrentCulture));
259             }
260         }
261 
262         protected internal bool DragDropEnabled {
263             get {
264                 return (!DesignMode &&
265                         RenderClientScript &&
266                         AllowLayoutChange &&
267                         WebPartManager != null &&
268                         WebPartManager.DisplayMode.AllowPageDesign);
269             }
270         }
271 
272         [
273         DefaultValue(typeof(Color), "Blue"),
274         TypeConverterAttribute(typeof(WebColorConverter)),
275         WebCategory("Appearance"),
276         WebSysDescription(SR.WebPartZoneBase_DragHighlightColor),
277         ]
278         public virtual Color DragHighlightColor {
279             get {
280                 object o = ViewState["DragHighlightColor"];
281                 if (o != null) {
282                     Color c = (Color)o;
283                     if (c.IsEmpty == false) {
284                         return c;
285                     }
286                 }
287                 return Color.Blue;
288             }
289             set {
290                 ViewState["DragHighlightColor"] = value;
291             }
292         }
293 
294         [
295         DefaultValue(null),
296         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
297         NotifyParentProperty(true),
298         PersistenceMode(PersistenceMode.InnerProperty),
299         WebCategory("Verbs"),
300         WebSysDescription(SR.WebPartZoneBase_EditVerb),
301         ]
302         public virtual WebPartVerb EditVerb {
303             get {
304                 if (_editVerb == null) {
305                     _editVerb = new WebPartEditVerb();
306                     if (IsTrackingViewState) {
307                         ((IStateManager)_editVerb).TrackViewState();
308                     }
309                 }
310                 return _editVerb;
311             }
312         }
313 
314         [
315         WebSysDefaultValue(SR.WebPartZoneBase_DefaultEmptyZoneText)
316         ]
317         public override string EmptyZoneText {
318             // Must look at viewstate directly instead of the property in the base class,
319             // so we can distinguish between an unset property and a property set to String.Empty.
320             get {
321                 string s = (string)ViewState["EmptyZoneText"];
322                 return((s == null) ? SR.GetString(SR.WebPartZoneBase_DefaultEmptyZoneText) : s);
323             }
324             set {
325                 ViewState["EmptyZoneText"] = value;
326             }
327         }
328 
329         [
330         DefaultValue(null),
331         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
332         NotifyParentProperty(true),
333         PersistenceMode(PersistenceMode.InnerProperty),
334         WebCategory("Verbs"),
335         WebSysDescription(SR.WebPartZoneBase_ExportVerb),
336         ]
337         public virtual WebPartVerb ExportVerb {
338             get {
339                 if (_exportVerb == null) {
340                     _exportVerb = new WebPartExportVerb();
341                     if (IsTrackingViewState) {
342                         ((IStateManager)_exportVerb).TrackViewState();
343                     }
344                 }
345 
346                 return _exportVerb;
347             }
348         }
349 
350         protected override bool HasFooter {
351             get {
352                 return false;
353             }
354         }
355 
356         protected override bool HasHeader {
357             get {
358                 bool hasHeader = false;
359                 if (DesignMode) {
360                     hasHeader = true;
361                 }
362                 else if (WebPartManager != null) {
363                     hasHeader = WebPartManager.DisplayMode.AllowPageDesign;
364                 }
365                 return hasHeader;
366             }
367         }
368 
369         [
370         DefaultValue(null),
371         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
372         NotifyParentProperty(true),
373         PersistenceMode(PersistenceMode.InnerProperty),
374         WebCategory("Verbs"),
375         WebSysDescription(SR.WebPartZoneBase_HelpVerb),
376         ]
377         public virtual WebPartVerb HelpVerb {
378             get {
379                 if (_helpVerb == null) {
380                     _helpVerb = new WebPartHelpVerb();
381                     if (IsTrackingViewState) {
382                         ((IStateManager)_helpVerb).TrackViewState();
383                     }
384                 }
385 
386                 return _helpVerb;
387             }
388         }
389 
390         internal WebPartMenu Menu {
391             get {
392                 if (_menu == null) {
393                     _menu = new WebPartMenu(this);
394                 }
395                 return _menu;
396             }
397         }
398 
399         [
400         DefaultValue(null),
401         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
402         NotifyParentProperty(true),
403         PersistenceMode(PersistenceMode.InnerProperty),
404         WebCategory("Styles"),
405         WebSysDescription(SR.WebPartZoneBase_MenuCheckImageStyle)
406         ]
407         public Style MenuCheckImageStyle {
408             get {
409                 if (_menuCheckImageStyle == null) {
410                     _menuCheckImageStyle = new Style();
411                     if (IsTrackingViewState) {
412                         ((IStateManager)_menuCheckImageStyle).TrackViewState();
413                     }
414                 }
415 
416                 return _menuCheckImageStyle;
417             }
418         }
419 
420         /// <devdoc>
421         /// </devdoc>
422         [
423         DefaultValue(""),
424         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
425         UrlProperty(),
426         WebCategory("Appearance"),
427         WebSysDescription(SR.WebPartZoneBase_MenuCheckImageUrl)
428         ]
429         public virtual string MenuCheckImageUrl {
430             get {
431                 string s = (string)ViewState["MenuCheckImageUrl"];
432                 return ((s == null) ? String.Empty : s);
433             }
434             set {
435                 ViewState["MenuCheckImageUrl"] = value;
436             }
437         }
438 
439         [
440         DefaultValue(null),
441         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
442         NotifyParentProperty(true),
443         PersistenceMode(PersistenceMode.InnerProperty),
444         WebCategory("Styles"),
445         WebSysDescription(SR.WebPartZoneBase_MenuLabelHoverStyle)
446         ]
447         public Style MenuLabelHoverStyle {
448             get {
449                 if (_menuLabelHoverStyle == null) {
450                     _menuLabelHoverStyle = new Style();
451                     if (IsTrackingViewState) {
452                         ((IStateManager)_menuLabelHoverStyle).TrackViewState();
453                     }
454                 }
455 
456                 return _menuLabelHoverStyle;
457             }
458         }
459 
460         [
461         DefaultValue(null),
462         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
463         NotifyParentProperty(true),
464         PersistenceMode(PersistenceMode.InnerProperty),
465         WebCategory("Styles"),
466         WebSysDescription(SR.WebPartZoneBase_MenuLabelStyle)
467         ]
468         public Style MenuLabelStyle {
469             get {
470                 if (_menuLabelStyle == null) {
471                     _menuLabelStyle = new Style();
472                     if (IsTrackingViewState) {
473                         ((IStateManager)_menuLabelStyle).TrackViewState();
474                     }
475                 }
476 
477                 return _menuLabelStyle;
478             }
479         }
480 
481         [
482         DefaultValue(""),
483         Localizable(true),
484         WebCategory("Appearance"),
485         WebSysDescription(SR.WebPartZoneBase_MenuLabelText)
486         ]
487         public virtual string MenuLabelText {
488             get {
489                 string s = (string)ViewState["MenuLabelText"];
490                 return ((s == null) ? String.Empty : s);
491             }
492             set {
493                 ViewState["MenuLabelText"] = value;
494             }
495         }
496 
497         /// <devdoc>
498         /// </devdoc>
499         [
500         DefaultValue(""),
501         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
502         UrlProperty(),
503         WebCategory("Appearance"),
504         WebSysDescription(SR.WebPartZoneBase_MenuPopupImageUrl)
505         ]
506         public virtual string MenuPopupImageUrl {
507             get {
508                 string s = (string)ViewState["MenuPopupImageUrl"];
509                 return ((s == null) ? String.Empty : s);
510             }
511             set {
512                 ViewState["MenuPopupImageUrl"] = value;
513             }
514         }
515 
516         [
517         DefaultValue(null),
518         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
519         NotifyParentProperty(true),
520         PersistenceMode(PersistenceMode.InnerProperty),
521         WebCategory("Styles"),
522         WebSysDescription(SR.WebPartZoneBase_MenuPopupStyle)
523         ]
524         public WebPartMenuStyle MenuPopupStyle {
525             get {
526                 if (_menuPopupStyle == null) {
527                     _menuPopupStyle = new WebPartMenuStyle();
528                     if (IsTrackingViewState) {
529                         ((IStateManager)_menuPopupStyle).TrackViewState();
530                     }
531                 }
532 
533                 return _menuPopupStyle;
534             }
535         }
536 
537         [
538         DefaultValue(null),
539         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
540         NotifyParentProperty(true),
541         PersistenceMode(PersistenceMode.InnerProperty),
542         WebCategory("Styles"),
543         WebSysDescription(SR.WebPartZoneBase_MenuVerbHoverStyle)
544         ]
545         public Style MenuVerbHoverStyle {
546             get {
547                 if (_menuVerbHoverStyle == null) {
548                     _menuVerbHoverStyle = new Style();
549                     if (IsTrackingViewState) {
550                         ((IStateManager)_menuVerbHoverStyle).TrackViewState();
551                     }
552                 }
553 
554                 return _menuVerbHoverStyle;
555             }
556         }
557 
558         [
559         DefaultValue(null),
560         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
561         NotifyParentProperty(true),
562         PersistenceMode(PersistenceMode.InnerProperty),
563         WebCategory("Styles"),
564         WebSysDescription(SR.WebPartZoneBase_MenuVerbStyle)
565         ]
566         public Style MenuVerbStyle {
567             get {
568                 if (_menuVerbStyle == null) {
569                     _menuVerbStyle = new Style();
570                     if (IsTrackingViewState) {
571                         ((IStateManager)_menuVerbStyle).TrackViewState();
572                     }
573                 }
574 
575                 return _menuVerbStyle;
576             }
577         }
578 
579         [
580         DefaultValue(null),
581         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
582         NotifyParentProperty(true),
583         PersistenceMode(PersistenceMode.InnerProperty),
584         WebCategory("Verbs"),
585         WebSysDescription(SR.WebPartZoneBase_MinimizeVerb),
586         ]
587         public virtual WebPartVerb MinimizeVerb {
588             get {
589                 if (_minimizeVerb == null) {
590                     _minimizeVerb = new WebPartMinimizeVerb();
591                     if (IsTrackingViewState) {
592                         ((IStateManager)_minimizeVerb).TrackViewState();
593                     }
594                 }
595 
596                 return _minimizeVerb;
597             }
598         }
599 
600         /// <devdoc>
601         /// The direction in which contained web parts are rendered.
602         /// </devdoc>
603         [
604         DefaultValue(Orientation.Vertical),
605         WebCategory("Layout"),
606         WebSysDescription(SR.WebPartZoneBase_LayoutOrientation),
607         ]
608         public virtual Orientation LayoutOrientation {
609             get {
610                 object o = ViewState["LayoutOrientation"];
611                 return (o != null) ? (Orientation)(int)o : Orientation.Vertical;
612             }
613             set {
614                 if ((value < Orientation.Horizontal) || (value > Orientation.Vertical)) {
615                     throw new ArgumentOutOfRangeException("value");
616                 }
617 
618                 ViewState["LayoutOrientation"] = (int)value;
619             }
620         }
621 
622         [
623         DefaultValue(null),
624         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
625         NotifyParentProperty(true),
626         PersistenceMode(PersistenceMode.InnerProperty),
627         WebCategory("Verbs"),
628         WebSysDescription(SR.WebPartZoneBase_RestoreVerb),
629         ]
630         public virtual WebPartVerb RestoreVerb {
631             get {
632                 if (_restoreVerb == null) {
633                     _restoreVerb = new WebPartRestoreVerb();
634                     if (IsTrackingViewState) {
635                         ((IStateManager)_restoreVerb).TrackViewState();
636                     }
637                 }
638 
639                 return _restoreVerb;
640             }
641         }
642 
643         [
644         DefaultValue(null),
645         NotifyParentProperty(true),
646         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
647         PersistenceMode(PersistenceMode.InnerProperty),
648         WebCategory("WebPart"),
649         WebSysDescription(SR.WebPartZoneBase_SelectedPartChromeStyle),
650         ]
651         public Style SelectedPartChromeStyle {
652             get {
653                 if (_selectedPartChromeStyle == null) {
654                     _selectedPartChromeStyle = new Style();
655                     if (IsTrackingViewState) {
656                         ((IStateManager)_selectedPartChromeStyle).TrackViewState();
657                     }
658                 }
659 
660                 return _selectedPartChromeStyle;
661             }
662         }
663 
664         /// <devdoc>
665         /// Shows the icon image in the title bar of a part, if the TitleIconImageUrl is specified for a part.
666         /// </devdoc>
667         [
668         DefaultValue(true),
669         WebCategory("WebPart"),
670         WebSysDescription(SR.WebPartZoneBase_ShowTitleIcons),
671         ]
672         public virtual bool ShowTitleIcons {
673             get {
674                 object b = ViewState["ShowTitleIcons"];
675                 return (b != null) ? (bool)b : true;
676             }
677             set {
678                 ViewState["ShowTitleIcons"] = value;
679             }
680         }
681 
682         [
683         DefaultValue(ButtonType.Image),
684         WebCategory("Appearance"),
685         WebSysDescription(SR.WebPartZoneBase_TitleBarVerbButtonType),
686         ]
687         public virtual ButtonType TitleBarVerbButtonType {
688             get {
689                 object obj = ViewState["TitleBarVerbButtonType"];
690                 return (obj == null) ? ButtonType.Image : (ButtonType)obj;
691             }
692             set {
693                 if (value < ButtonType.Button || value > ButtonType.Link) {
694                     throw new ArgumentOutOfRangeException("value");
695                 }
696                 ViewState["TitleBarVerbButtonType"] = value;
697             }
698         }
699 
700         [
701         DefaultValue(null),
702         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
703         NotifyParentProperty(true),
704         PersistenceMode(PersistenceMode.InnerProperty),
705         WebCategory("Styles"),
706         WebSysDescription(SR.WebPartZoneBase_TitleBarVerbStyle)
707         ]
708         public Style TitleBarVerbStyle {
709             get {
710                 if (_titleBarVerbStyle == null) {
711                     _titleBarVerbStyle = new Style();
712                     if (IsTrackingViewState) {
713                         ((IStateManager)_titleBarVerbStyle).TrackViewState();
714                     }
715                 }
716 
717                 return _titleBarVerbStyle;
718             }
719         }
720 
721         [
722         Browsable(false),
723         EditorBrowsable(EditorBrowsableState.Never),
724         Themeable(false)
725         ]
726         public override ButtonType VerbButtonType {
727             get {
728                 return base.VerbButtonType;
729             }
730             set {
731                 base.VerbButtonType = value;
732             }
733         }
734 
735         [
736         Browsable(false),
737         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
738         ]
739         public WebPartChrome WebPartChrome {
740             get {
741                 if (_webPartChrome == null) {
742                     _webPartChrome = CreateWebPartChrome();
743                 }
744                 return _webPartChrome;
745             }
746         }
747 
748         //
749         [
750         Browsable(false),
751         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
752         ]
753         public WebPartCollection WebParts {
754             get {
755                 WebPartCollection webParts;
756                 if (DesignMode) {
757                     WebPart[] parts = new WebPart[Controls.Count];
758                     Controls.CopyTo(parts, 0);
759                     return new WebPartCollection(parts);
760                 }
761                 else {
762                     if (WebPartManager != null) {
763                         webParts = WebPartManager.GetWebPartsForZone(this);
764                     }
765                     else {
766                         webParts = new WebPartCollection();
767                     }
768                 }
769 
770                 return webParts;
771             }
772         }
773 
774         [
775         DefaultValue(WebPartVerbRenderMode.Menu),
776         WebCategory("WebPart"),
777         WebSysDescription(SR.WebPartZoneBase_WebPartVerbRenderMode)
778         ]
779         public virtual WebPartVerbRenderMode WebPartVerbRenderMode {
780             get {
781                 object o = ViewState["WebPartVerbRenderMode"];
782                 return (o != null) ? (WebPartVerbRenderMode)(int)o : WebPartVerbRenderMode.Menu;
783             }
784             set {
785                 if ((value < WebPartVerbRenderMode.Menu) || (value > WebPartVerbRenderMode.TitleBar)) {
786                     throw new ArgumentOutOfRangeException("value");
787                 }
788                 ViewState["WebPartVerbRenderMode"] = (int)value;
789             }
790         }
791 
792         [
793         WebCategory("Action"),
794         WebSysDescription(SR.WebPartZoneBase_CreateVerbs)
795         ]
796         public event WebPartVerbsEventHandler CreateVerbs {
797             add {
798                 Events.AddHandler(CreateVerbsEvent, value);
799             }
800             remove {
801                 Events.RemoveHandler(CreateVerbsEvent, value);
802             }
803         }
804 
CloseWebPart(WebPart webPart)805         protected virtual void CloseWebPart(WebPart webPart) {
806             if (webPart == null) {
807                 throw new ArgumentNullException("webPart");
808             }
809             if (WebPartManager != null && webPart.AllowClose && AllowLayoutChange) {
810                 WebPartManager.CloseWebPart(webPart);
811             }
812         }
813 
ConnectWebPart(WebPart webPart)814         protected virtual void ConnectWebPart(WebPart webPart) {
815             if (webPart == null) {
816                 throw new ArgumentNullException("webPart");
817             }
818             if (WebPartManager != null &&
819                 WebPartManager.DisplayMode == WebPartManager.ConnectDisplayMode &&
820                 webPart != WebPartManager.SelectedWebPart &&
821                 webPart.AllowConnect) {
822                 WebPartManager.BeginWebPartConnecting(webPart);
823             }
824         }
825 
826         //
CreateChildControls()827         protected internal override void CreateChildControls() {
828             if (DesignMode) {
829                 Controls.Clear();
830 
831                 WebPartCollection webParts = GetInitialWebParts();
832                 foreach (WebPart part in webParts) {
833                     Controls.Add(part);
834                 }
835             }
836         }
837 
838         /// <internalonly/>
CreateControlCollection()839         protected override ControlCollection CreateControlCollection() {
840             if (DesignMode) {
841                 return new ControlCollection(this);
842             }
843             else {
844                 return new EmptyControlCollection(this);
845             }
846         }
847 
CreateControlStyle()848         protected override Style CreateControlStyle() {
849             // We need the ControlStyle to use its own StateBag, since we do not want the
850             // default values we set here to be saved in ViewState.
851             Style style = new Style();
852 
853             style.BorderColor = Color.Gray;
854             style.BorderStyle = BorderStyle.Solid;
855             style.BorderWidth = 1;
856 
857             return style;
858         }
859 
860         /// <devdoc>
861         /// Overridden by subclasses to use a different chrome when rendering the WebParts.
862         /// </devdoc>
CreateWebPartChrome()863         protected virtual WebPartChrome CreateWebPartChrome() {
864             return new WebPartChrome(this, WebPartManager);
865         }
866 
DeleteWebPart(WebPart webPart)867         protected virtual void DeleteWebPart(WebPart webPart) {
868             if (webPart == null) {
869                 throw new ArgumentNullException("webPart");
870             }
871             if (WebPartManager != null && AllowLayoutChange) {
872                 WebPartManager.DeleteWebPart(webPart);
873             }
874         }
875 
EditWebPart(WebPart webPart)876         protected virtual void EditWebPart(WebPart webPart) {
877             if (webPart == null) {
878                 throw new ArgumentNullException("webPart");
879             }
880             if (WebPartManager != null &&
881                 WebPartManager.DisplayMode == WebPartManager.EditDisplayMode &&
882                 webPart != WebPartManager.SelectedWebPart) {
883                 WebPartManager.BeginWebPartEditing(webPart);
884             }
885         }
886 
887         /// <devdoc>
888         /// The effective frame type of a part, taking into consideration the PartChromeType
889         /// of the zone and the DisplayMode of the page.
890         /// </devdoc>
GetEffectiveChromeType(Part part)891         public override PartChromeType GetEffectiveChromeType(Part part) {
892             PartChromeType chromeType = base.GetEffectiveChromeType(part);
893 
894             // Add title to chromeType if we are in page design mode.  We always want
895             // to render a title bar when in page design mode. (VSWhidbey 77730)
896             if ((WebPartManager != null) && (WebPartManager.DisplayMode.AllowPageDesign)) {
897                 if (chromeType == PartChromeType.None) {
898                     chromeType = PartChromeType.TitleOnly;
899                 }
900                 else if (chromeType == PartChromeType.BorderOnly) {
901                     chromeType = PartChromeType.TitleAndBorder;
902                 }
903             }
904 
905             return chromeType;
906         }
907 
908         /// <devdoc>
909         /// Loads the initial web parts from a template, persistence medium, or some other way.
910         /// These parts may be in a different zone when rendered, since control personalization
911         /// may change their zone.
912         /// </devdoc>
GetInitialWebParts()913         protected internal abstract WebPartCollection GetInitialWebParts();
914 
LoadViewState(object savedState)915         protected override void LoadViewState(object savedState) {
916             if (savedState == null) {
917                 base.LoadViewState(null);
918             }
919             else {
920                 object[] myState = (object[]) savedState;
921                 if (myState.Length != viewStateArrayLength) {
922                     throw new ArgumentException(SR.GetString(SR.ViewState_InvalidViewState));
923                 }
924 
925                 base.LoadViewState(myState[baseIndex]);
926                 if (myState[selectedPartChromeStyleIndex] != null) {
927                     ((IStateManager) SelectedPartChromeStyle).LoadViewState(myState[selectedPartChromeStyleIndex]);
928                 }
929                 if (myState[closeVerbIndex] != null) {
930                     ((IStateManager) CloseVerb).LoadViewState(myState[closeVerbIndex]);
931                 }
932                 if (myState[connectVerbIndex] != null) {
933                     ((IStateManager) ConnectVerb).LoadViewState(myState[connectVerbIndex]);
934                 }
935                 if (myState[deleteVerbIndex] != null) {
936                     ((IStateManager) DeleteVerb).LoadViewState(myState[deleteVerbIndex]);
937                 }
938                 if (myState[editVerbIndex] != null) {
939                     ((IStateManager) EditVerb).LoadViewState(myState[editVerbIndex]);
940                 }
941                 if (myState[helpVerbIndex] != null) {
942                     ((IStateManager) HelpVerb).LoadViewState(myState[helpVerbIndex]);
943                 }
944                 if (myState[minimizeVerbIndex] != null) {
945                     ((IStateManager) MinimizeVerb).LoadViewState(myState[minimizeVerbIndex]);
946                 }
947                 if (myState[restoreVerbIndex] != null) {
948                     ((IStateManager) RestoreVerb).LoadViewState(myState[restoreVerbIndex]);
949                 }
950                 if (myState[exportVerbIndex] != null) {
951                     ((IStateManager) ExportVerb).LoadViewState(myState[exportVerbIndex]);
952                 }
953                 if (myState[menuPopupStyleIndex] != null) {
954                     ((IStateManager) MenuPopupStyle).LoadViewState(myState[menuPopupStyleIndex]);
955                 }
956                 if (myState[menuLabelStyleIndex] != null) {
957                     ((IStateManager) MenuLabelStyle).LoadViewState(myState[menuLabelStyleIndex]);
958                 }
959                 if (myState[menuLabelHoverStyleIndex] != null) {
960                     ((IStateManager) MenuLabelHoverStyle).LoadViewState(myState[menuLabelHoverStyleIndex]);
961                 }
962                 if (myState[menuCheckImageStyleIndex] != null) {
963                     ((IStateManager) MenuCheckImageStyle).LoadViewState(myState[menuCheckImageStyleIndex]);
964                 }
965                 if (myState[menuVerbStyleIndex] != null) {
966                     ((IStateManager) MenuVerbStyle).LoadViewState(myState[menuVerbStyleIndex]);
967                 }
968                 if (myState[menuVerbHoverStyleIndex] != null) {
969                     ((IStateManager) MenuVerbHoverStyle).LoadViewState(myState[menuVerbHoverStyleIndex]);
970                 }
971                 if (myState[controlStyleIndex] != null) {
972                     ((IStateManager) ControlStyle).LoadViewState(myState[controlStyleIndex]);
973                 }
974                 if (myState[titleBarVerbStyleIndex] != null) {
975                     ((IStateManager) TitleBarVerbStyle).LoadViewState(myState[titleBarVerbStyleIndex]);
976                 }
977             }
978         }
979 
980         /// <devdoc>
981         /// Load the verbs defined by the page developer or zone subclass.
982         /// </devdoc>
CreateZoneVerbs()983         private void CreateZoneVerbs() {
984             WebPartVerbsEventArgs args = new WebPartVerbsEventArgs();
985             OnCreateVerbs(args);
986             _verbs = args.Verbs;
987         }
988 
IsDefaultVerbEvent(string[] eventArguments)989         private bool IsDefaultVerbEvent(string[] eventArguments) {
990             return (eventArguments.Length == 2);
991         }
992 
IsDragEvent(string[] eventArguments)993         private bool IsDragEvent(string[] eventArguments) {
994             return (eventArguments.Length == 3 &&
995                     String.Equals(eventArguments[0], dragEventArgument, StringComparison.OrdinalIgnoreCase));
996         }
997 
IsPartVerbEvent(string[] eventArguments)998         private bool IsPartVerbEvent(string[] eventArguments) {
999             return (eventArguments.Length == 3 &&
1000                     String.Equals(eventArguments[0], partVerbEventArgument, StringComparison.OrdinalIgnoreCase));
1001         }
1002 
IsZoneVerbEvent(string[] eventArguments)1003         private bool IsZoneVerbEvent(string[] eventArguments) {
1004             return (eventArguments.Length == 3 &&
1005                     String.Equals(eventArguments[0], zoneVerbEventArgument, StringComparison.OrdinalIgnoreCase));
1006         }
1007 
MinimizeWebPart(WebPart webPart)1008         protected virtual void MinimizeWebPart(WebPart webPart) {
1009             if (webPart == null) {
1010                 throw new ArgumentNullException("webPart");
1011             }
1012             if (webPart.ChromeState == PartChromeState.Normal &&
1013                 webPart.AllowMinimize &&
1014                 AllowLayoutChange) {
1015                 webPart.ChromeState = PartChromeState.Minimized;
1016             }
1017         }
1018 
OnCreateVerbs(WebPartVerbsEventArgs e)1019         protected virtual void OnCreateVerbs(WebPartVerbsEventArgs e) {
1020             WebPartVerbsEventHandler handler = (WebPartVerbsEventHandler)Events[CreateVerbsEvent];
1021             if (handler != null) {
1022                 handler(this, e);
1023             }
1024         }
1025 
OnPreRender(EventArgs e)1026         protected internal override void OnPreRender(EventArgs e) {
1027             base.OnPreRender(e);
1028 
1029             // The zone verbs may have been loaded in RaisePostBackEvent, but we must load
1030             // them again in case the page developer wants to change the verbs at this time.
1031             CreateZoneVerbs();
1032 
1033             WebPartChrome.PerformPreRender();
1034 
1035             //
1036 
1037         }
1038 
RaisePostBackEvent(string eventArgument)1039         protected virtual void RaisePostBackEvent(string eventArgument) {
1040             if (String.IsNullOrEmpty(eventArgument)) {
1041                 return;
1042             }
1043 
1044             string[] eventArguments = eventArgument.Split(eventArgumentSeparatorChar);
1045 
1046             // We do not register all the possible combinations of drag/drop events because there are
1047             // too many combinations.  So we must not validate them either.  VSWhidbey 492706
1048             if (!IsDragEvent(eventArguments)) {
1049                 ValidateEvent(UniqueID, eventArgument);
1050             }
1051 
1052             if (WebPartManager == null) {
1053                 return;
1054             }
1055 
1056             // Look in collection of all WebParts instead of WebParts for this zone, since
1057             // an admin may have moved the part to a different Zone between postbacks.
1058             WebPartCollection allWebParts = WebPartManager.WebParts;
1059             if (IsDefaultVerbEvent(eventArguments)) {
1060                 // Postback from a default verb
1061                 string verbEventArgument = eventArguments[0];
1062                 string partID = eventArguments[1];
1063                 WebPart part = allWebParts[partID];
1064 
1065                 // Part will be null or closed if the part was present on the previous request,
1066                 // but is missing or closed now.  It may have been deleted or closed by the admin
1067                 // or filtered by roles.
1068                 if (part != null && !part.IsClosed) {
1069                     if (String.Equals(verbEventArgument, closeEventArgument, StringComparison.OrdinalIgnoreCase)) {
1070                         if (CloseVerb.Visible && CloseVerb.Enabled) {
1071                             CloseWebPart(part);
1072                         }
1073                     }
1074                     else if (String.Equals(verbEventArgument, connectEventArgument, StringComparison.OrdinalIgnoreCase)) {
1075                         if (ConnectVerb.Visible && ConnectVerb.Enabled) {
1076                             ConnectWebPart(part);
1077                         }
1078                     }
1079                     else if (String.Equals(verbEventArgument, deleteEventArgument, StringComparison.OrdinalIgnoreCase)) {
1080                         if (DeleteVerb.Visible && DeleteVerb.Enabled) {
1081                             DeleteWebPart(part);
1082                         }
1083                     }
1084                     else if (String.Equals(verbEventArgument, editEventArgument, StringComparison.OrdinalIgnoreCase)) {
1085                         if (EditVerb.Visible && EditVerb.Enabled) {
1086                             EditWebPart(part);
1087                         }
1088                     }
1089                     else if (String.Equals(verbEventArgument, minimizeEventArgument, StringComparison.OrdinalIgnoreCase)) {
1090                         if (MinimizeVerb.Visible && MinimizeVerb.Enabled) {
1091                             MinimizeWebPart(part);
1092                         }
1093                     }
1094                     else if (String.Equals(verbEventArgument, restoreEventArgument, StringComparison.OrdinalIgnoreCase)) {
1095                         if (RestoreVerb.Visible && RestoreVerb.Enabled) {
1096                             RestoreWebPart(part);
1097                         }
1098                     }
1099                 }
1100             }
1101             else if (IsDragEvent(eventArguments)) {
1102                 // Postback from a drop event
1103 
1104                 // The eventArgument contains the WholePartID instead of just ID, since we
1105                 // render WholePartID on the table containing the whole part.
1106                 string wholePartID = eventArguments[1];
1107 
1108                 string partID = null;
1109                 if (wholePartID.StartsWith(WebPart.WholePartIDPrefix, StringComparison.Ordinal)) {
1110                     partID = wholePartID.Substring(WebPart.WholePartIDPrefix.Length);
1111                 }
1112 
1113                 int dropPartIndex = Int32.Parse(eventArguments[2], CultureInfo.InvariantCulture);
1114                 WebPart actionPart = allWebParts[partID];
1115 
1116                 // Part will be null or closed if the part was present on the previous request,
1117                 // but is missing or closed now.  It may have been deleted or closed by the admin
1118                 // or filtered by roles.
1119                 if (actionPart != null && !actionPart.IsClosed) {
1120                     // If dragged part to larger index in its current zone, correct drop index
1121                     // by subtracting 1.  Otherwise the part will move 1 position farther than desired.
1122                     if (WebParts.Contains(actionPart) && (actionPart.ZoneIndex < dropPartIndex)) {
1123                         dropPartIndex--;
1124                     }
1125 
1126                     WebPartZoneBase fromZone = actionPart.Zone;
1127                     if (AllowLayoutChange &&
1128                         WebPartManager.DisplayMode.AllowPageDesign &&
1129                         fromZone != null &&
1130                         fromZone.AllowLayoutChange &&
1131                         (actionPart.AllowZoneChange || (fromZone == this))) {
1132                         WebPartManager.MoveWebPart(actionPart, this, dropPartIndex);
1133                     }
1134                 }
1135             }
1136             else if (IsPartVerbEvent(eventArguments)) {
1137                 // Postback from a part verb
1138                 string verbID = eventArguments[1];
1139                 string partID = eventArguments[2];
1140                 WebPart part = allWebParts[partID];
1141 
1142                 // Part will be null or closed if the part was present on the previous request,
1143                 // but is missing or closed now.  It may have been deleted or closed by the admin
1144                 // or filtered by roles.
1145                 if (part != null && !part.IsClosed) {
1146                     WebPartVerb verb = part.Verbs[verbID];
1147                     if (verb != null && verb.Visible && verb.Enabled) {
1148                         verb.ServerClickHandler(verb, new WebPartEventArgs(part));
1149                     }
1150                 }
1151             }
1152             else if (IsZoneVerbEvent(eventArguments)) {
1153                 // Postback from a zone verb
1154                 CreateZoneVerbs();
1155                 string verbID = eventArguments[1];
1156                 string partID = eventArguments[2];
1157                 WebPart part = allWebParts[partID];
1158 
1159                 // Part will be null or closed if the part was present on the previous request,
1160                 // but is missing or closed now.  It may have been deleted or closed by the admin
1161                 // or filtered by roles.
1162                 if (part != null && !part.IsClosed) {
1163                     WebPartVerb verb = _verbs[verbID];
1164                     if (verb != null && verb.Visible && verb.Enabled) {
1165                         verb.ServerClickHandler(verb, new WebPartEventArgs(part));
1166                     }
1167                 }
1168             }
1169         }
1170 
Render(HtmlTextWriter writer)1171         protected internal override void Render(HtmlTextWriter writer) {
1172             if (Page != null) {
1173                 Page.VerifyRenderingInServerForm(this);
1174             }
1175 
1176             _borderColor = BorderColor;
1177             _borderStyle = BorderStyle;
1178             _borderWidth = BorderWidth;
1179 
1180             // PERF: If the control style has not been created, we don't need to set these values,
1181             // since no style properties will be rendered
1182             if (ControlStyleCreated) {
1183                 BorderColor = Color.Empty;
1184                 BorderStyle = BorderStyle.NotSet;
1185                 BorderWidth = Unit.Empty;
1186             }
1187 
1188             base.Render(writer);
1189 
1190             if (ControlStyleCreated) {
1191                 BorderColor = _borderColor;
1192                 BorderStyle = _borderStyle;
1193                 BorderWidth = _borderWidth;
1194             }
1195         }
1196 
RenderBody(HtmlTextWriter writer)1197         protected override void RenderBody(HtmlTextWriter writer) {
1198             Orientation orientation = LayoutOrientation;
1199 
1200             if (DesignMode || (WebPartManager != null && (WebPartManager.DisplayMode.AllowPageDesign))) {
1201                 if (_borderColor != Color.Empty || _borderStyle != BorderStyle.NotSet || _borderWidth != Unit.Empty) {
1202                     Style s = new Style();
1203                     s.BorderColor = _borderColor;
1204                     s.BorderStyle = _borderStyle;
1205                     s.BorderWidth = _borderWidth;
1206                     s.AddAttributesToRender(writer, this);
1207                 }
1208             }
1209 
1210             RenderBodyTableBeginTag(writer);
1211             if (DesignMode) {
1212                 RenderDesignerRegionBeginTag(writer, orientation);
1213             }
1214 
1215             if (orientation == Orientation.Horizontal) {
1216                 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
1217             }
1218 
1219             bool dragDropEnabled = DragDropEnabled;
1220             if (dragDropEnabled) {
1221                 RenderDropCue(writer);
1222             }
1223 
1224             WebPartCollection webParts = WebParts;
1225             if (webParts == null || webParts.Count == 0) {
1226                 RenderEmptyZoneBody(writer);
1227             }
1228             else {
1229                 WebPartChrome chrome = WebPartChrome;
1230                 foreach (WebPart webPart in webParts) {
1231                     // Don't render anything visible for a  minimized part if its effective frame
1232                     // type dictates that a title bar will not be rendered. (VSWhidbey 77730)
1233                     if (webPart.ChromeState == PartChromeState.Minimized) {
1234                         PartChromeType chromeType = GetEffectiveChromeType(webPart);
1235                         if (chromeType == PartChromeType.None || chromeType == PartChromeType.BorderOnly) {
1236                             writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none");
1237                         }
1238                     }
1239 
1240 
1241                     if (orientation == Orientation.Vertical) {
1242                         writer.RenderBeginTag(HtmlTextWriterTag.Tr);
1243                     }
1244                     else {
1245                         // Mac IE needs height=100% set on <td> instead of <tr>
1246                         writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%");
1247                         writer.AddAttribute(HtmlTextWriterAttribute.Valign, "top");
1248                     }
1249                     writer.RenderBeginTag(HtmlTextWriterTag.Td);
1250 
1251                     chrome.RenderWebPart(writer, webPart);
1252 
1253                     writer.RenderEndTag();      // Td
1254                     if (orientation == Orientation.Vertical) {
1255                         writer.RenderEndTag();  // Tr
1256                     }
1257 
1258                     if (dragDropEnabled) {
1259                         RenderDropCue(writer);
1260                     }
1261                 }
1262 
1263                 if (orientation == Orientation.Vertical) {
1264                     // Add an extra row with height of 100%, to Microsoft up any extra space
1265                     // if the height of the zone is larger than its contents
1266                     writer.RenderBeginTag(HtmlTextWriterTag.Tr);
1267 
1268                     // Mozilla renders padding on an empty TD without this attribute
1269                     writer.AddStyleAttribute(HtmlTextWriterStyle.Padding, "0");
1270 
1271                     // Mac IE needs height=100% set on <td> instead of <tr>
1272                     writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%");
1273 
1274                     writer.RenderBeginTag(HtmlTextWriterTag.Td);
1275                     writer.RenderEndTag(); // Td
1276                     writer.RenderEndTag(); // Tr
1277                 }
1278                 else {
1279                     // Add an extra cell with width of 100%, to Microsoft up any extra space
1280                     // if the width of the zone is larger than its contents.
1281                     writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
1282 
1283                     // Mozilla renders padding on an empty TD without this attribute
1284                     writer.AddStyleAttribute(HtmlTextWriterStyle.Padding, "0");
1285 
1286                     writer.RenderBeginTag(HtmlTextWriterTag.Td);
1287                     writer.RenderEndTag(); // Td
1288                 }
1289             }
1290 
1291             if (orientation == Orientation.Horizontal) {
1292                 writer.RenderEndTag();  // Tr
1293             }
1294 
1295             if (DesignMode) {
1296                 RenderDesignerRegionEndTag(writer);
1297             }
1298             RenderBodyTableEndTag(writer);
1299         }
1300 
RenderDropCue(HtmlTextWriter writer)1301         protected virtual void RenderDropCue(HtmlTextWriter writer) {
1302             if (LayoutOrientation == Orientation.Vertical) {
1303                 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
1304                 writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingTop, "1");
1305                 writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingBottom, "1");
1306                 writer.RenderBeginTag(HtmlTextWriterTag.Td);
1307                 RenderDropCueIBar(writer, Orientation.Horizontal);
1308                 writer.RenderEndTag();  // Td
1309                 writer.RenderEndTag();  // Tr
1310             }
1311             else {
1312                 writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, "1");
1313                 writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingRight, "1");
1314                 writer.RenderBeginTag(HtmlTextWriterTag.Td);
1315                 RenderDropCueIBar(writer, Orientation.Vertical);
1316                 writer.RenderEndTag();  // Td
1317             }
1318         }
1319 
RenderDropCueIBar(HtmlTextWriter writer, Orientation orientation)1320         private void RenderDropCueIBar(HtmlTextWriter writer, Orientation orientation) {
1321             // 10px is the total margin and border width that we have to substract
1322             // (2*2px for the margin, 2*3px for the border)
1323             // Places to touch if we want to change the rendering of the cues:
1324             // WebParts.js (Zone_ToggleDropCues)
1325             // WebPartZoneBase.RenderDropCueIBar
1326             string color = ColorTranslator.ToHtml(DragHighlightColor);
1327             string border = "solid 3px " + color;
1328 
1329             writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
1330             writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
1331             writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
1332             if (orientation == Orientation.Horizontal) {
1333                 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
1334                 writer.AddStyleAttribute("border-left", border);
1335                 writer.AddStyleAttribute("border-right", border);
1336             }
1337             else {
1338                 writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%");
1339                 writer.AddStyleAttribute("border-top", border);
1340                 writer.AddStyleAttribute("border-bottom", border);
1341             }
1342             writer.AddStyleAttribute(HtmlTextWriterStyle.Visibility, "hidden");
1343             writer.RenderBeginTag(HtmlTextWriterTag.Table);
1344             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
1345 
1346             if (orientation == Orientation.Vertical) {
1347                 writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
1348             }
1349             writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "0px");
1350             writer.RenderBeginTag(HtmlTextWriterTag.Td);
1351 
1352             if (orientation == Orientation.Horizontal) {
1353                 writer.AddStyleAttribute(HtmlTextWriterStyle.Margin, "2px 0px 2px 0px");
1354                 writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "2px");
1355                 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
1356             }
1357             else {
1358                 writer.AddStyleAttribute(HtmlTextWriterStyle.Margin, "0px 2px 0px 2px");
1359                 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "2px");
1360                 writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%");
1361             }
1362             writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, color);
1363             writer.RenderBeginTag(HtmlTextWriterTag.Div);
1364 
1365             writer.RenderEndTag();      // Div
1366             writer.RenderEndTag();      // Td
1367             writer.RenderEndTag();      // Tr
1368             writer.RenderEndTag();      // Table
1369         }
1370 
RenderEmptyZoneBody(HtmlTextWriter writer)1371         private void RenderEmptyZoneBody(HtmlTextWriter writer) {
1372             bool vertical = (LayoutOrientation == Orientation.Vertical);
1373             bool horizontal = !vertical;
1374             string emptyZoneText = EmptyZoneText;
1375 
1376             bool renderText = (!DesignMode && AllowLayoutChange && WebPartManager != null &&
1377                                WebPartManager.DisplayMode.AllowPageDesign && !String.IsNullOrEmpty(emptyZoneText));
1378 
1379             if (vertical) {
1380                 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
1381             }
1382 
1383             if (renderText) {
1384                 writer.AddAttribute(HtmlTextWriterAttribute.Valign, "top");
1385             }
1386 
1387             if (horizontal) {
1388                 // Want drop zone to shrink to size, so take up all width in zone
1389                 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
1390             }
1391             else {
1392                 // Want drop zone to shrink to size, so take up all height in zone
1393                 // Mac IE needs height=100% set on <td> instead of <tr>
1394                 writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%");
1395             }
1396 
1397             writer.RenderBeginTag(HtmlTextWriterTag.Td);
1398 
1399             if (renderText) {
1400                 Style emptyZoneTextStyle = EmptyZoneTextStyle;
1401                 if (!emptyZoneTextStyle.IsEmpty) {
1402                     emptyZoneTextStyle.AddAttributesToRender(writer, this);
1403                 }
1404 
1405                 writer.RenderBeginTag(HtmlTextWriterTag.Div);
1406                 writer.Write(emptyZoneText);
1407                 writer.RenderEndTag();  // Div
1408             }
1409 
1410             writer.RenderEndTag();  // Td
1411             if (vertical) {
1412                 writer.RenderEndTag();  // Tr
1413             }
1414 
1415             if (renderText) {
1416                 if (DragDropEnabled) {
1417                     // This drop cue will never be activated since there are no web parts, but it
1418                     // reserves space below the text equal to the real drop cue above the text
1419                     RenderDropCue(writer);
1420                 }
1421             }
1422         }
1423 
RenderHeader(HtmlTextWriter writer)1424         protected override void RenderHeader(HtmlTextWriter writer) {
1425 
1426             //
1427 
1428 
1429 
1430 
1431             // Render title bar
1432             writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
1433             writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "2");
1434             writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
1435             writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
1436 
1437             TitleStyle headerStyle = HeaderStyle;
1438             if (!headerStyle.IsEmpty) {
1439                 // Apply font and forecolor from HeaderStyle to inner table
1440                 Style style = new Style();
1441                 if (!headerStyle.ForeColor.IsEmpty) {
1442                     style.ForeColor = headerStyle.ForeColor;
1443                 }
1444                 style.Font.CopyFrom(headerStyle.Font);
1445                 if (!headerStyle.Font.Size.IsEmpty) {
1446                     // If the font size is specified on the HeaderStyle, force the font size to 100%,
1447                     // so it inherits the font size from its parent in IE compatibility mode. I would
1448                     // think that "1em" would work here as well, but "1em" doesn't work when you change
1449                     // the font size in the browser.
1450                     style.Font.Size = new FontUnit(new Unit(100, UnitType.Percentage));
1451                 }
1452                 if (!style.IsEmpty) {
1453                     style.AddAttributesToRender(writer, this);
1454                 }
1455             }
1456 
1457             writer.RenderBeginTag(HtmlTextWriterTag.Table);
1458 
1459             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
1460 
1461             // Copied from Panel.cs
1462             //
1463             HorizontalAlign hAlign = headerStyle.HorizontalAlign;
1464             if (hAlign != HorizontalAlign.NotSet) {
1465                 TypeConverter hac = TypeDescriptor.GetConverter(typeof(HorizontalAlign));
1466                 writer.AddAttribute(HtmlTextWriterAttribute.Align, hac.ConvertToString(hAlign));
1467             }
1468 
1469             writer.AddStyleAttribute(HtmlTextWriterStyle.WhiteSpace, "nowrap");
1470             writer.RenderBeginTag(HtmlTextWriterTag.Td);
1471             writer.Write(DisplayTitle);
1472             writer.RenderEndTag();  // Td
1473 
1474             writer.RenderEndTag();  // Tr
1475             writer.RenderEndTag();  // Table
1476         }
1477 
RestoreWebPart(WebPart webPart)1478         protected virtual void RestoreWebPart(WebPart webPart) {
1479             if (webPart == null) {
1480                 throw new ArgumentNullException("webPart");
1481             }
1482             if ((webPart.ChromeState == PartChromeState.Minimized) && AllowLayoutChange) {
1483                 webPart.ChromeState = PartChromeState.Normal;
1484             }
1485         }
1486 
SaveViewState()1487         protected override object SaveViewState() {
1488             object[] myState = new object[viewStateArrayLength];
1489 
1490             myState[baseIndex] = base.SaveViewState();
1491             myState[selectedPartChromeStyleIndex] = (_selectedPartChromeStyle != null) ? ((IStateManager)_selectedPartChromeStyle).SaveViewState() : null;
1492             myState[closeVerbIndex] = (_closeVerb != null) ? ((IStateManager)_closeVerb).SaveViewState() : null;
1493             myState[connectVerbIndex] = (_connectVerb != null) ? ((IStateManager)_connectVerb).SaveViewState() : null;
1494             myState[deleteVerbIndex] = (_deleteVerb != null) ? ((IStateManager)_deleteVerb).SaveViewState() : null;
1495             myState[editVerbIndex] = (_editVerb != null) ? ((IStateManager)_editVerb).SaveViewState() : null;
1496             myState[helpVerbIndex] = (_helpVerb != null) ? ((IStateManager)_helpVerb).SaveViewState() : null;
1497             myState[minimizeVerbIndex] = (_minimizeVerb != null) ? ((IStateManager)_minimizeVerb).SaveViewState() : null;
1498             myState[restoreVerbIndex] = (_restoreVerb != null) ? ((IStateManager)_restoreVerb).SaveViewState() : null;
1499             myState[exportVerbIndex] = (_exportVerb != null) ? ((IStateManager)_exportVerb).SaveViewState() : null;
1500             myState[menuPopupStyleIndex] = (_menuPopupStyle != null) ? ((IStateManager)_menuPopupStyle).SaveViewState() : null;
1501             myState[menuLabelStyleIndex] = (_menuLabelStyle != null) ? ((IStateManager)_menuLabelStyle).SaveViewState() : null;
1502             myState[menuLabelHoverStyleIndex] = (_menuLabelHoverStyle != null) ? ((IStateManager)_menuLabelHoverStyle).SaveViewState() : null;
1503             myState[menuCheckImageStyleIndex] = (_menuCheckImageStyle != null) ? ((IStateManager)_menuCheckImageStyle).SaveViewState() : null;
1504             myState[menuVerbStyleIndex] = (_menuVerbStyle != null) ? ((IStateManager)_menuVerbStyle).SaveViewState() : null;
1505             myState[menuVerbHoverStyleIndex] = (_menuVerbHoverStyle != null) ? ((IStateManager)_menuVerbHoverStyle).SaveViewState() : null;
1506             myState[controlStyleIndex] = ControlStyleCreated ? ((IStateManager)ControlStyle).SaveViewState() : null;
1507             myState[titleBarVerbStyleIndex] = (_titleBarVerbStyle != null) ? ((IStateManager)_titleBarVerbStyle).SaveViewState() : null;
1508 
1509             for (int i=0; i < viewStateArrayLength; i++) {
1510                 if (myState[i] != null) {
1511                     return myState;
1512                 }
1513             }
1514 
1515             // More performant to return null than an array of null values
1516             return null;
1517         }
1518 
TrackViewState()1519         protected override void TrackViewState() {
1520             base.TrackViewState();
1521 
1522             if (_selectedPartChromeStyle != null) {
1523                 ((IStateManager) _selectedPartChromeStyle).TrackViewState();
1524             }
1525             if (_closeVerb != null) {
1526                 ((IStateManager) _closeVerb).TrackViewState();
1527             }
1528             if (_connectVerb != null) {
1529                 ((IStateManager) _connectVerb).TrackViewState();
1530             }
1531             if (_deleteVerb != null) {
1532                 ((IStateManager) _deleteVerb).TrackViewState();
1533             }
1534             if (_editVerb != null) {
1535                 ((IStateManager) _editVerb).TrackViewState();
1536             }
1537             if (_helpVerb != null) {
1538                 ((IStateManager) _helpVerb).TrackViewState();
1539             }
1540             if (_minimizeVerb != null) {
1541                 ((IStateManager) _minimizeVerb).TrackViewState();
1542             }
1543             if (_restoreVerb != null) {
1544                 ((IStateManager) _restoreVerb).TrackViewState();
1545             }
1546             if (_exportVerb != null) {
1547                 ((IStateManager) _exportVerb).TrackViewState();
1548             }
1549             if (_menuPopupStyle != null) {
1550                 ((IStateManager) _menuPopupStyle).TrackViewState();
1551             }
1552             if (_menuLabelStyle != null) {
1553                 ((IStateManager) _menuLabelStyle).TrackViewState();
1554             }
1555             if (_menuLabelHoverStyle != null) {
1556                 ((IStateManager) _menuLabelHoverStyle).TrackViewState();
1557             }
1558             if (_menuCheckImageStyle != null) {
1559                 ((IStateManager) _menuCheckImageStyle).TrackViewState();
1560             }
1561             if (_menuVerbStyle != null) {
1562                 ((IStateManager) _menuVerbStyle).TrackViewState();
1563             }
1564             if (_menuVerbHoverStyle != null) {
1565                 ((IStateManager)_menuVerbHoverStyle).TrackViewState();
1566             }
1567             if (ControlStyleCreated) {
1568                 ((IStateManager) ControlStyle).TrackViewState();
1569             }
1570             if (_titleBarVerbStyle != null) {
1571                 ((IStateManager)_titleBarVerbStyle).TrackViewState();
1572             }
1573         }
1574 
1575         // Called from WebPartChrome and DesignerWebPartChrome.  Can't be passed as argument to
1576         // RenderWebPart, since the WebPartZoneDesigner calls RenderWebPart as well.
VerbsForWebPart(WebPart webPart)1577         internal WebPartVerbCollection VerbsForWebPart(WebPart webPart) {
1578             WebPartVerbCollection verbs = new WebPartVerbCollection();
1579 
1580             WebPartVerbCollection partVerbs = webPart.Verbs;
1581             if (partVerbs != null) {
1582                 foreach (WebPartVerb verb in partVerbs) {
1583                     if (verb.ServerClickHandler != null) {
1584                         verb.SetEventArgumentPrefix(partVerbEventArgumentWithSeparator);
1585                     }
1586                     verbs.Add(verb);
1587                 }
1588             }
1589 
1590             if (_verbs != null) {
1591                 foreach (WebPartVerb verb in _verbs) {
1592                     if (verb.ServerClickHandler != null) {
1593                         verb.SetEventArgumentPrefix(zoneVerbEventArgumentWithSeparator);
1594                     }
1595                     verbs.Add(verb);
1596                 }
1597             }
1598 
1599             WebPartVerb minimizeVerb = MinimizeVerb;
1600             minimizeVerb.SetEventArgumentPrefix(minimizeEventArgumentWithSeparator);
1601             verbs.Add(minimizeVerb);
1602 
1603             WebPartVerb restoreVerb = RestoreVerb;
1604             restoreVerb.SetEventArgumentPrefix(restoreEventArgumentWithSeparator);
1605             verbs.Add(restoreVerb);
1606 
1607             WebPartVerb closeVerb = CloseVerb;
1608             closeVerb.SetEventArgumentPrefix(closeEventArgumentWithSeparator);
1609             verbs.Add(closeVerb);
1610 
1611             WebPartVerb deleteVerb = DeleteVerb;
1612             deleteVerb.SetEventArgumentPrefix(deleteEventArgumentWithSeparator);
1613             verbs.Add(deleteVerb);
1614 
1615             WebPartVerb editVerb = EditVerb;
1616             editVerb.SetEventArgumentPrefix(editEventArgumentWithSeparator);
1617             verbs.Add(editVerb);
1618 
1619             WebPartVerb connectVerb = ConnectVerb;
1620             connectVerb.SetEventArgumentPrefix(connectEventArgumentWithSeparator);
1621             verbs.Add(connectVerb);
1622 
1623             // Export does not post back
1624             verbs.Add(ExportVerb);
1625 
1626             // Help verb does not post back
1627             verbs.Add(HelpVerb);
1628 
1629             return verbs;
1630         }
1631 
1632         #region Implementation of IPostBackEventHandler
1633         /// <internalonly/>
IPostBackEventHandler.RaisePostBackEvent(string eventArgument)1634         void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
1635             RaisePostBackEvent(eventArgument);
1636         }
1637         #endregion
1638 
1639         #region Implementation of IWebPartMenuUser
1640         Style IWebPartMenuUser.CheckImageStyle {
1641             get {
1642                 return _menuCheckImageStyle;
1643             }
1644         }
1645 
1646         string IWebPartMenuUser.CheckImageUrl {
1647             get {
1648                 string s = MenuCheckImageUrl;
1649                 if (!String.IsNullOrEmpty(s)) {
1650                     s = ResolveClientUrl(s);
1651                 }
1652                 return s;
1653             }
1654         }
1655 
1656         string IWebPartMenuUser.ClientID {
1657             get {
1658                 return ClientID;
1659             }
1660         }
1661 
1662         string IWebPartMenuUser.PopupImageUrl {
1663             get {
1664                 string s = MenuPopupImageUrl;
1665                 if (!String.IsNullOrEmpty(s)) {
1666                     s = ResolveClientUrl(s);
1667                 }
1668                 return s;
1669             }
1670         }
1671 
1672         Style IWebPartMenuUser.ItemHoverStyle {
1673             get {
1674                 return _menuVerbHoverStyle;
1675             }
1676         }
1677 
1678         Style IWebPartMenuUser.ItemStyle {
1679             get {
1680                 return _menuVerbStyle;
1681             }
1682         }
1683 
1684         Style IWebPartMenuUser.LabelHoverStyle {
1685             get {
1686                 return _menuLabelHoverStyle;
1687             }
1688         }
1689 
1690         string IWebPartMenuUser.LabelImageUrl {
1691             get {
1692                 return null;
1693             }
1694         }
1695 
1696         Style IWebPartMenuUser.LabelStyle {
1697             get {
1698                 return MenuLabelStyle;
1699             }
1700         }
1701 
1702         string IWebPartMenuUser.LabelText {
1703             get {
1704                 return MenuLabelText;
1705             }
1706         }
1707 
1708         WebPartMenuStyle IWebPartMenuUser.MenuPopupStyle {
1709             get {
1710                 return _menuPopupStyle;
1711             }
1712         }
1713 
1714         Page IWebPartMenuUser.Page {
1715             get {
1716                 return Page;
1717             }
1718         }
1719 
1720         string IWebPartMenuUser.PostBackTarget {
1721             get {
1722                 return UniqueID;
1723             }
1724         }
1725 
1726         IUrlResolutionService IWebPartMenuUser.UrlResolver {
1727             get {
1728                 return this;
1729             }
1730         }
1731 
IWebPartMenuUser.OnBeginRender(HtmlTextWriter writer)1732         void IWebPartMenuUser.OnBeginRender(HtmlTextWriter writer) {
1733         }
1734 
IWebPartMenuUser.OnEndRender(HtmlTextWriter writer)1735         void IWebPartMenuUser.OnEndRender(HtmlTextWriter writer) {
1736         }
1737         #endregion
1738     }
1739 }
1740