2 // System.Web.UI.TemplateControl.cs
5 // Duncan Mak (duncan@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
9 // (C) 2002 Ximian, Inc. (http://www.ximian.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.ComponentModel;
36 using System.Reflection;
38 using System.Web.Compilation;
39 using System.Web.Util;
41 namespace System.Web.UI {
43 public abstract class TemplateControl : Control, INamingContainer
45 static object abortTransaction = new object ();
46 static object commitTransaction = new object ();
47 static object error = new object ();
48 static string [] methodNames = { "Page_Init",
55 "Page_AbortTransaction",
56 "Page_CommitTransaction" };
58 const BindingFlags bflags = BindingFlags.Public |
59 BindingFlags.NonPublic |
60 BindingFlags.Instance;
63 protected TemplateControl ()
71 [EditorBrowsable (EditorBrowsableState.Never)]
72 protected virtual int AutoHandlers {
77 [EditorBrowsable (EditorBrowsableState.Never)]
78 protected virtual bool SupportAutoEvents {
86 protected virtual void Construct ()
91 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
98 internal void WireupAutomaticEvents ()
100 if (!SupportAutoEvents || !AutoEventWireup)
103 Type type = GetType ();
104 foreach (string methodName in methodNames) {
105 MethodInfo method = type.GetMethod (methodName, bflags);
109 if (method.DeclaringType != type) {
110 if (!method.IsPublic && !method.IsFamilyOrAssembly &&
111 !method.IsFamilyAndAssembly && !method.IsFamily)
115 if (method.ReturnType != typeof (void))
118 ParameterInfo [] parms = method.GetParameters ();
119 int length = parms.Length;
120 bool noParams = (length == 0);
121 if (!noParams && (length != 2 ||
122 parms [0].ParameterType != typeof (object) ||
123 parms [1].ParameterType != typeof (EventArgs)))
126 int pos = methodName.IndexOf ("_");
127 string eventName = methodName.Substring (pos + 1);
128 EventInfo evt = type.GetEvent (eventName);
130 /* This should never happen */
135 NoParamsInvoker npi = new NoParamsInvoker (this, methodName);
136 evt.AddEventHandler (this, npi.FakeDelegate);
138 evt.AddEventHandler (this, Delegate.CreateDelegate (
139 typeof (EventHandler), this, methodName));
144 [EditorBrowsable (EditorBrowsableState.Never)]
145 protected virtual void FrameworkInitialize ()
149 Type GetTypeFromControlPath (string virtualPath)
151 if (virtualPath == null)
152 throw new ArgumentNullException ("virtualPath");
154 string vpath = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
155 string realpath = Context.Request.MapPath (vpath);
156 return UserControlParser.GetCompiledType (vpath, realpath, Context);
159 public Control LoadControl (string virtualPath)
161 object control = Activator.CreateInstance (GetTypeFromControlPath (virtualPath));
162 if (control is UserControl)
163 ((UserControl) control).InitializeAsUserControl (Page);
165 return (Control) control;
168 public ITemplate LoadTemplate (string virtualPath)
170 Type t = GetTypeFromControlPath (virtualPath);
171 return new SimpleTemplate (t);
174 protected virtual void OnAbortTransaction (EventArgs e)
176 EventHandler eh = Events [abortTransaction] as EventHandler;
181 protected virtual void OnCommitTransaction (EventArgs e)
183 EventHandler eh = Events [commitTransaction] as EventHandler;
188 protected virtual void OnError (EventArgs e)
190 EventHandler eh = Events [error] as EventHandler;
196 public Control ParseControl (string content)
202 [EditorBrowsable (EditorBrowsableState.Never)]
203 public static object ReadStringResource (Type t)
209 [EditorBrowsable (EditorBrowsableState.Never)]
210 protected void SetStringResourcePointer (object stringResourcePointer,
211 int maxResourceOffset)
216 [EditorBrowsable (EditorBrowsableState.Never)]
217 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
218 int size, bool fAsciiOnly)
226 [WebSysDescription ("Raised when the user aborts a transaction.")]
227 public event EventHandler AbortTransaction {
228 add { Events.AddHandler (abortTransaction, value); }
229 remove { Events.RemoveHandler (abortTransaction, value); }
232 [WebSysDescription ("Raised when the user initiates a transaction.")]
233 public event EventHandler CommitTransaction {
234 add { Events.AddHandler (commitTransaction, value); }
235 remove { Events.RemoveHandler (commitTransaction, value); }
238 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
239 public event EventHandler Error {
240 add { Events.AddHandler (error, value); }
241 remove { Events.RemoveHandler (error, value); }
246 class SimpleTemplate : ITemplate
250 public SimpleTemplate (Type type)
255 public void InstantiateIn (Control control)
257 Control template = Activator.CreateInstance (type) as Control;
258 template.SetBindingContainer (false);
259 control.Controls.Add (template);
267 internal void PushDataItemContext (object o)
269 if (dataItemCtx == null)
270 dataItemCtx = new Stack ();
272 dataItemCtx.Push (o);
275 internal void PopDataItemContext ()
277 if (dataItemCtx == null)
278 throw new InvalidOperationException ();
283 internal object CurrentDataItem {
285 if (dataItemCtx == null || dataItemCtx.Count == 0)
286 throw new InvalidOperationException ("No data item");
288 return dataItemCtx.Peek ();
292 protected object Eval (string expression)
294 return DataBinder.Eval (CurrentDataItem, expression);
297 protected object Eval (string expression, string format)
299 return DataBinder.Eval (CurrentDataItem, expression, format);
302 protected object XPath (string xpathexpression)
304 return XPathBinder.Eval (CurrentDataItem, xpathexpression);
307 protected object XPath (string xpathexpression, string format)
309 return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
312 protected IEnumerable XPathSelect (string xpathexpression)
314 return XPathBinder.Select (CurrentDataItem, xpathexpression);