I'm trying to build a control that makes a consistent popup window appearance using the ModalPopupExtender. It worked fine in the "Atlas" builds, but now with the renamed "Ajax" builds it no longer does.
What now happens is when I click the trigger control, it posts back to the server and refreshes the entire page. After it has posted back if I click the trigger control again, THEN the popup will appear.
I'll post the code for my control and try to add some comments so you can tell what I'm up to:
1
2 [ParseChildren(false)]
3 [PersistChildren(true)]
4 public class ModalWindow : IDMControl, INamingContainer
5 {
6 private ModalPopupExtender extender;
7 private Panel panel;
8 private UpdatePanel body;
9 private ImageButton closeBox;
10 private Button hiddenShowButton;
11
12 private string targetControlID;
13 private string title;
14
15 public string TargetControlID
16 {
17 get { return targetControlID; }
18 set { targetControlID = value; }
19 }
20
21 public string Title
22 {
23 get { return title; }
24 set { title = value; }
25 }
26
27 // Controls added to the HTML tag on the page actually get added to the internal UpdatePanel's controls.
28 public override ControlCollection Controls
29 {
30 get
31 {
32 EnsureChildControls();
33 return body.ContentTemplateContainer.Controls;
34 }
35 }
36
37 // This is so I can easily get at the actual child controls collection
38 // for the "wrap" controls like the close button, update panel, etc.
39 private ControlCollection MyControls
40 {
41 get { return base.Controls; }
42 }
43
44 // This is another double-check to make sure that HTML-added controls
45 // are added to the update panel, not the direct child controls collection
46 protected override void AddParsedSubObject(object obj)
47 {
48 EnsureChildControls();
49 Control c = obj as Control;
50 if (c != null)
51 {
52 body.ContentTemplateContainer.Controls.Add(c);
53 }
54
55 }
56
57 protected override void CreateChildControls()
58 {
59 MyControls.Clear();
60
61 // This is the panel that gets displayed/hidden
62 panel = new Panel();
63 panel.ID = "PopupPanel";
64 panel.CssClass = "ModalWindow";
65 MyControls.Add(panel);
66
67 // This is the update panel so that postbacks can occur inside the dialog
68 // without posting back the entire page (which would get rid of the dialog)
69 body = new UpdatePanel();
70 body.ID = "body";
71 body.UpdateMode = UpdatePanelUpdateMode.Conditional;
72 body.RenderMode = UpdatePanelRenderMode.Block;
73 panel.Controls.Add(body);
74
75 // This is the X box in the upper-right
76 closeBox = new ImageButton();
77 closeBox.ID = "Close";
78 closeBox.AlternateText = "Close";
79 closeBox.ImageUrl = "/images/close.gif";
80 closeBox.ToolTip = "Close Window";
81 MyControls.Add(closeBox);
82
83 // Extender is supposed to display PopupPanel when <targetControlID>,
84 // in my case the ID of a LinkButton outside this control, is clicked.
85 extender = new ModalPopupExtender();
86 extender.ID = "MPE";
87 extender.PopupControlID = "PopupPanel";
88 extender.BackgroundCssClass = "ModalBackground";
89 extender.DropShadow = true;
90 extender.Enabled = true;
91 extender.TargetControlID = targetControlID;
92 extender.CancelControlID = "Close";
93 MyControls.Add(extender);
94 }
95
96 // The extender is rendered, then the show/hide panel. Inside that panel, markup
97 // to make a header bar and border, plus the close box is rendered. After that,
98 // the UpdatePanel (body) is rendered which contains whatever the contents of the
99 // <IDM:ModalWindow /> tag are.
100 protected override void Render(HtmlTextWriter w)
101 {
102 panel.Width = (this.Width == Unit.Empty) ? Unit.Pixel(500) : this.Width;
103 panel.Height = (this.Height == Unit.Empty) ? Unit.Pixel(400) : this.Height;
104
105 extender.RenderControl(w);
106 panel.RenderBeginTag(w);
107
108 // Header
109 w.AddAttribute(HtmlTextWriterAttribute.Class, "Header");
110 w.RenderBeginTag(HtmlTextWriterTag.Div);
111 w.AddAttribute(HtmlTextWriterAttribute.Class, "FloatRight");
112 w.RenderBeginTag(HtmlTextWriterTag.Span);
113 closeBox.RenderControl(w);
114 w.RenderEndTag();
115 w.Write(title ?? "Popup Window");
116 w.RenderEndTag();
117
118 // Body
119 w.AddAttribute(HtmlTextWriterAttribute.Class, "Body");
120 w.RenderBeginTag(HtmlTextWriterTag.Div);
121 body.RenderControl(w);
122 w.RenderEndTag();
123
124 panel.RenderEndTag(w);
125 }
126
127 }
And so the behavior is like this:
- Load Page
- Click the TargetControlID - Page refreshes and a bunch of WebResource.axd scripts that weren't previously on the page are rendered.
- Click the TargetControlID again, and the modal window appears.
I'm fairly sure that the problem is related to the WebResource.axd scripts not rendering to the page on the first try - but I don't know how to correct it.