2003-10-13 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI / TemplateControl.cs
1 //
2 // System.Web.UI.TemplateControl.cs
3 //
4 // Authors:
5 //   Duncan Mak  (duncan@ximian.com)
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //
9 // (C) 2002 Ximian, Inc. (http://www.ximian.com)
10 //
11
12 using System;
13 using System.Collections;
14 using System.ComponentModel;
15 using System.Reflection;
16 using System.Web.Compilation;
17 using System.Web.Util;
18
19 namespace System.Web.UI {
20
21         public abstract class TemplateControl : Control, INamingContainer
22         {
23                 static object abortTransaction = new object ();
24                 static object commitTransaction = new object ();
25                 static object error = new object ();
26                 static string [] methodNames = { "Page_Init",
27                                                  "Page_Load",
28                                                  "Page_DataBind",
29                                                  "Page_PreRender",
30                                                  "Page_Dispose",
31                                                  "Page_Error" };
32
33                 const BindingFlags bflags = BindingFlags.Public |
34                                             BindingFlags.NonPublic |
35                                             BindingFlags.Instance;
36
37                 #region Constructor
38                 protected TemplateControl ()
39                 {
40                         Construct ();
41                 }
42
43                 #endregion
44
45                 #region Properties
46
47                 protected virtual int AutoHandlers {
48                         get { return 0; }
49                         set { }
50                 }
51
52                 protected virtual bool SupportAutoEvents {
53                         get { return true; }
54                 }
55
56                 #endregion
57
58                 #region Methods
59
60                 protected virtual void Construct ()
61                 {
62                 }
63
64                 [MonoTODO]
65                 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
66                                                                                     int size,
67                                                                                     bool fAsciiOnly)
68                 {
69                         return null;
70                 }
71
72                 internal void WireupAutomaticEvents ()
73                 {
74                         if (!SupportAutoEvents || !AutoEventWireup)
75                                 return;
76
77                         Type type = GetType ();
78                         foreach (MethodInfo method in type.GetMethods (bflags)) {
79                                 int pos = Array.IndexOf (methodNames, method.Name);
80                                 if (pos == -1)
81                                         continue;
82
83                                 string name = methodNames [pos];
84                                 pos = name.IndexOf ("_");
85                                 if (pos == -1 || pos + 1 == name.Length)
86                                         continue;
87
88                                 if (method.ReturnType != typeof (void))
89                                         continue;
90
91                                 ParameterInfo [] parms = method.GetParameters ();
92                                 int length = parms.Length;
93                                 bool noParams = (length == 0);
94                                 if (!noParams && (parms.Length != 2 ||
95                                     parms [0].ParameterType != typeof (object) ||
96                                     parms [1].ParameterType != typeof (EventArgs)))
97                                     continue;
98
99                                 string eventName = name.Substring (pos + 1);
100                                 EventInfo evt = type.GetEvent (eventName);
101                                 if (evt == null)
102                                         continue;
103
104                                 if (noParams) {
105                                         NoParamsInvoker npi = new NoParamsInvoker (this, method.Name);
106                                         evt.AddEventHandler (this, npi.FakeDelegate);
107                                 } else {
108                                         evt.AddEventHandler (this, Delegate.CreateDelegate (
109                                                         typeof (EventHandler), this, method.Name));
110                                 }
111                         }
112                 }
113
114                 [EditorBrowsable (EditorBrowsableState.Never)]
115                 protected virtual void FrameworkInitialize ()
116                 {
117                 }
118
119                 Type GetTypeFromControlPath (string virtualPath)
120                 {
121                         if (virtualPath == null)
122                                 throw new ArgumentNullException ("virtualPath");
123
124                         return UserControlParser.GetCompiledType (TemplateSourceDirectory, virtualPath, Context);
125                 }
126
127                 public Control LoadControl (string virtualPath)
128                 {
129                         object control = Activator.CreateInstance (GetTypeFromControlPath (virtualPath));
130                         if (control is UserControl)
131                                 ((UserControl) control).InitializeAsUserControl (Page);
132
133                         return (Control) control;
134                 }
135
136                 public ITemplate LoadTemplate (string virtualPath)
137                 {
138                         Type t = GetTypeFromControlPath (virtualPath);
139                         return new SimpleTemplate (t);
140                 }
141
142                 protected virtual void OnAbortTransaction (EventArgs e)
143                 {
144                         EventHandler eh = Events [error] as EventHandler;
145                         if (eh != null)
146                                 eh (this, e);
147                 }
148
149                 protected virtual void OnCommitTransaction (EventArgs e)
150                 {
151                         EventHandler eh = Events [commitTransaction] as EventHandler;
152                         if (eh != null)
153                                 eh (this, e);
154                 }
155
156                 protected virtual void OnError (EventArgs e)
157                 {
158                         EventHandler eh = Events [abortTransaction] as EventHandler;
159                         if (eh != null)
160                                 eh (this, e);
161                 }
162
163                 [MonoTODO]
164                 public Control ParseControl (string content)
165                 {
166                         return null;
167                 }
168
169                 [MonoTODO]
170                 [EditorBrowsable (EditorBrowsableState.Never)]
171                 public static object ReadStringResource (Type t)
172                 {
173                         return null;
174                 }
175
176                 [MonoTODO]
177                 [EditorBrowsable (EditorBrowsableState.Never)]
178                 protected void SetStringResourcePointer (object stringResourcePointer,
179                                                          int maxResourceOffset)
180                 {
181                 }
182
183                 [MonoTODO]
184                 [EditorBrowsable (EditorBrowsableState.Never)]
185                 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
186                                                         int size, bool fAsciiOnly)
187                 {
188                 }
189
190                 #endregion
191
192                 #region Events
193
194                 [WebSysDescription ("Raised when the user aborts a transaction.")]
195                 public event EventHandler AbortTransaction {
196                         add { Events.AddHandler (abortTransaction, value); }
197                         remove { Events.RemoveHandler (abortTransaction, value); }
198                 }
199
200                 [WebSysDescription ("Raised when the user initiates a transaction.")]
201                 public event EventHandler CommitTransaction {
202                         add { Events.AddHandler (commitTransaction, value); }
203                         remove { Events.RemoveHandler (commitTransaction, value); }
204                 }
205
206                 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
207                 public event EventHandler Error {
208                         add { Events.AddHandler (error, value); }
209                         remove { Events.RemoveHandler (error, value); }
210                 }
211
212                 #endregion
213
214                 class SimpleTemplate : ITemplate
215                 {
216                         Type type;
217
218                         public SimpleTemplate (Type type)
219                         {
220                                 this.type = type;
221                         }
222
223                         public void InstantiateIn (Control control)
224                         {
225                                 Control template = Activator.CreateInstance (type) as Control;
226                                 template.SetBindingContainer (false);
227                                 control.Controls.Add (template);
228                         }
229                 }
230
231                 delegate void NoParamsDelegate ();
232                 class NoParamsInvoker
233                 {
234                         EventHandler faked;
235                         NoParamsDelegate real;
236
237                         public NoParamsInvoker (object o, string method)
238                         {
239                                  real = (NoParamsDelegate) Delegate.CreateDelegate (
240                                                         typeof (NoParamsDelegate), o, method);
241                                  faked = new EventHandler (InvokeNoParams);
242                         }
243
244                         void InvokeNoParams (object o, EventArgs args)
245                         {
246                                 real ();
247                         }
248
249                         public EventHandler FakeDelegate {
250                                 get { return faked; }
251                         }
252                 }
253         }
254 }