1 //
2 // System.ComponentModel.Design.DesignSurface
3 //
4 // Authors:
5 //	  Ivan N. Zlatev (contact i-nZ.net)
6 //
7 // (C) 2006-2007 Ivan N. Zlatev
8 
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 
30 
31 using System;
32 using System.Collections;
33 using System.ComponentModel;
34 using System.ComponentModel.Design.Serialization;
35 using System.Reflection;
36 
37 namespace System.ComponentModel.Design
38 {
39 
40 	public class DesignSurface : IServiceProvider, IDisposable
41 	{
42 
43 #region DefaultDesignerLoader : DesignerLoader
44 
45 		internal class DefaultDesignerLoader : DesignerLoader
46 		{
47 			//  When DesignSurface.BeginLoad is invoked, the designer loader loads the design document, displays the designer
48 			//  surface using the IDesignerHost interface, and calls IDesignerLoaderHost.EndLoad
49 			//  when done. The IDesignerLoaderHost implementation is usually the same class that implements IDesignerHost.
50 
51 			// The designer loader informs the designer host that it needs to invoke a load or reload so that the designer
52 			// host can perform additional tasks at these times.
53 
54 			private Type _componentType;
55 			private bool _loading;
56 
57 
58 			public override bool Loading
59 			{
60 				get { return _loading; }
61 			}
62 
DefaultDesignerLoader(Type componentType)63 			public DefaultDesignerLoader (Type componentType)
64 			{
65 				if (componentType == null)
66 					throw new ArgumentNullException ("componentType");
67 
68 				_componentType = componentType;
69 			}
70 
71 			// Note that IDesignerLoader : IDesignerHost
72 			//
BeginLoad(IDesignerLoaderHost loaderHost)73 			public override void BeginLoad (IDesignerLoaderHost loaderHost)
74 			{
75 				_loading = true;
76 				// initializa root component and designer
77 				//
78 				loaderHost.CreateComponent (_componentType);
79 				// finish off loading - no error collection here.
80 				//
81 				loaderHost.EndLoad (_componentType.FullName, true, null);
82 				_loading = false;
83 			}
84 
Dispose()85 			public override void Dispose ()
86 			{
87 				_componentType = null;
88 			}
89 		} // DesignerLoader
90 
91 #endregion
92 
93 
94 
95 
96 		private DesignerHost _designerHost;
97 		private DesignSurfaceServiceContainer _serviceContainer;
98 		private ICollection _loadErrors;
99 		private bool _isLoaded;
100 		private DesignerLoader _designerLoader;
101 
102 
DesignSurface()103 		public DesignSurface () : this ((IServiceProvider) null)
104 		{
105 		}
106 
DesignSurface(Type rootComponentType)107 		public DesignSurface (Type rootComponentType) : this (null, rootComponentType)
108 		{
109 		}
110 
111 
DesignSurface(IServiceProvider parentProvider, Type rootComponentType)112 		public DesignSurface (IServiceProvider parentProvider, Type rootComponentType) : this (parentProvider)
113 		{
114 			if (rootComponentType == null)
115 				throw new System.ArgumentNullException ("rootComponentType");
116 
117 			BeginLoad (rootComponentType);
118 		}
119 
120 		// this ctor doesn't load the surface
121 		//
DesignSurface(IServiceProvider parentProvider)122 		public DesignSurface (IServiceProvider parentProvider)
123 		{
124 
125 			_serviceContainer = new DesignSurfaceServiceContainer (parentProvider);
126 			_serviceContainer.AddNonReplaceableService (typeof (IServiceContainer), _serviceContainer);
127 
128 			_designerHost = new DesignerHost ((IServiceProvider) _serviceContainer);
129 			_designerHost.DesignerLoaderHostLoaded += new LoadedEventHandler (OnDesignerHost_Loaded);
130 			_designerHost.DesignerLoaderHostLoading += new EventHandler (OnDesignerHost_Loading);
131 			_designerHost.DesignerLoaderHostUnloading += new EventHandler (OnDesignerHost_Unloading);
132 			_designerHost.DesignerLoaderHostUnloaded += new EventHandler (OnDesignerHost_Unloaded);
133 
134 			_designerHost.Activated += new EventHandler (OnDesignerHost_Activated);
135 
136 			_serviceContainer.AddNonReplaceableService (typeof (IComponentChangeService), _designerHost);
137 			_serviceContainer.AddNonReplaceableService (typeof (IDesignerHost), _designerHost);
138 			_serviceContainer.AddNonReplaceableService (typeof (IContainer), _designerHost);
139 			_serviceContainer.AddService (typeof (ITypeDescriptorFilterService),
140 							  (ITypeDescriptorFilterService) new TypeDescriptorFilterService (_serviceContainer));
141 
142 			ExtenderService extenderService = new ExtenderService ();
143 			_serviceContainer.AddService (typeof (IExtenderProviderService), (IExtenderProviderService) extenderService);
144 			_serviceContainer.AddService (typeof (IExtenderListService), (IExtenderListService) extenderService);
145 			_serviceContainer.AddService (typeof (DesignSurface), this);
146 
147 			SelectionService selectionService = new SelectionService (_serviceContainer);
148 			_serviceContainer.AddService (typeof (ISelectionService), (ISelectionService) selectionService);
149 		}
150 
151 		protected ServiceContainer ServiceContainer {
152 			get {
153 				if (_designerHost == null)
154 					throw new ObjectDisposedException ("DesignSurface");
155 
156 				return _serviceContainer;
157 			}
158 		}
159 
160 		public IContainer ComponentContainer {
161 			get {
162 				if (_designerHost == null)
163 					throw new ObjectDisposedException ("DesignSurface");
164 
165 				return _designerHost.Container;
166 			}
167 		}
168 
169 		public bool IsLoaded {
170 			get { return _isLoaded; }
171 		}
172 
173 		// Returns a collection of loading errors or a void collection.
174 		//
175 		public ICollection LoadErrors {
176 			get {
177 					if (_loadErrors == null)
178 						_loadErrors = new object[0];
179 
180 					return _loadErrors;
181 				}
182 		}
183 
184 		public object View {
185 			get {
186 				if (_designerHost == null)
187 					throw new ObjectDisposedException ("DesignSurface");
188 
189 				if (_designerHost.RootComponent == null || this.LoadErrors.Count > 0)
190 					throw new InvalidOperationException ("The DesignSurface isn't loaded.");
191 
192 				IRootDesigner designer = _designerHost.GetDesigner (_designerHost.RootComponent) as IRootDesigner;
193 				if (designer == null)
194 					throw new InvalidOperationException ("The DesignSurface isn't loaded.");
195 
196 				ViewTechnology[] viewTech = designer.SupportedTechnologies;
197 				for (int i = 0; i < viewTech.Length; i++) {
198 					try {
199 						return designer.GetView (viewTech[i]);
200 					} catch {}
201 				}
202 
203 				throw new NotSupportedException ("No supported View Technology found.");
204 			}
205 		}
206 
207 		public event EventHandler Disposed;
208 		public event EventHandler Flushed;
209 		public event LoadedEventHandler Loaded;
210 		public event EventHandler Loading;
211 		public event EventHandler Unloaded;
212 		public event EventHandler Unloading;
213 		public event EventHandler ViewActivated;
214 
BeginLoad(Type rootComponentType)215 		public void BeginLoad (Type rootComponentType)
216 		{
217 			if (rootComponentType == null)
218 				throw new System.ArgumentNullException ("rootComponentType");
219 			if (_designerHost == null)
220 				throw new ObjectDisposedException ("DesignSurface");
221 
222 			this.BeginLoad (new DefaultDesignerLoader (rootComponentType));
223 		}
224 
BeginLoad(DesignerLoader loader)225 		public void BeginLoad (DesignerLoader loader)
226 		{
227 			if (loader == null)
228 				throw new System.ArgumentNullException ("loader");
229 			if (_designerHost == null)
230 				throw new ObjectDisposedException ("DesignSurface");
231 
232 			if (!_isLoaded) {
233 				_loadErrors = null;
234 				_designerLoader = loader;
235 				this.OnLoading (EventArgs.Empty);
236 				_designerLoader.BeginLoad (_designerHost);
237 			}
238 		}
239 
240 
241 #region IDisposable
242 
Dispose()243 		public void Dispose ()
244 		{
245 			this.Dispose (true);
246 		}
247 
248 
Dispose(bool disposing)249 		protected virtual void Dispose (bool disposing)
250 		{
251 			if (_designerLoader != null) {
252 				_designerLoader.Dispose ();
253 				_designerLoader = null;
254 			}
255 			if (_designerHost != null) {
256 				_designerHost.Dispose ();
257 				_designerHost.DesignerLoaderHostLoaded -= new LoadedEventHandler (OnDesignerHost_Loaded);
258 				_designerHost.DesignerLoaderHostLoading -= new EventHandler (OnDesignerHost_Loading);
259 				_designerHost.DesignerLoaderHostUnloading -= new EventHandler (OnDesignerHost_Unloading);
260 				_designerHost.DesignerLoaderHostUnloaded -= new EventHandler (OnDesignerHost_Unloaded);
261 				_designerHost.Activated -= new EventHandler (OnDesignerHost_Activated);
262 				_designerHost = null;
263 			}
264 			if (_serviceContainer != null) {
265 				_serviceContainer.Dispose ();
266 				_serviceContainer = null;
267 			}
268 
269 			if (Disposed != null)
270 				Disposed (this, EventArgs.Empty);
271 		}
272 
273 #endregion
274 
275 
Flush()276 		public void Flush ()
277 		{
278 			if (_designerLoader != null)
279 				_designerLoader.Flush ();
280 
281 			if (Flushed != null)
282 				Flushed (this, EventArgs.Empty);
283 		}
284 
OnDesignerHost_Loaded(object sender, LoadedEventArgs e)285 		private void OnDesignerHost_Loaded (object sender, LoadedEventArgs e)
286 		{
287 			this.OnLoaded (e);
288 		}
289 
OnDesignerHost_Loading(object sender, EventArgs e)290 		private void OnDesignerHost_Loading (object sender, EventArgs e)
291 		{
292 			this.OnLoading (EventArgs.Empty);
293 		}
294 
295 
OnDesignerHost_Unloading(object sender, EventArgs e)296 		private void OnDesignerHost_Unloading (object sender, EventArgs e)
297 		{
298 			this.OnUnloading (EventArgs.Empty);
299 		}
300 
301 
OnDesignerHost_Unloaded(object sender, EventArgs e)302 		private void OnDesignerHost_Unloaded (object sender, EventArgs e)
303 		{
304 			this.OnUnloaded (EventArgs.Empty);
305 		}
306 
OnLoaded(LoadedEventArgs e)307 		protected virtual void OnLoaded (LoadedEventArgs e)
308 		{
309 			_loadErrors = e.Errors;
310 			_isLoaded = e.HasSucceeded;
311 
312 			if (Loaded != null)
313 				Loaded (this, e);
314 		}
315 
OnLoading(EventArgs e)316 		protected virtual void OnLoading (EventArgs e)
317 		{
318 			if (Loading != null)
319 				Loading (this, e);
320 		}
321 
322 
OnUnloaded(EventArgs e)323 		protected virtual void OnUnloaded (EventArgs e)
324 		{
325 			if (Unloaded != null)
326 				Unloaded (this, e);
327 		}
328 
329 
OnUnloading(EventArgs e)330 		protected virtual void OnUnloading (EventArgs e)
331 		{
332 			if (Unloading != null)
333 				Unloading (this, e);
334 		}
335 
OnDesignerHost_Activated(object sender, EventArgs args)336 		internal void OnDesignerHost_Activated (object sender, EventArgs args)
337 		{
338 			this.OnViewActivate (EventArgs.Empty);
339 		}
340 
OnViewActivate(EventArgs e)341 		protected virtual void OnViewActivate (EventArgs e)
342 		{
343 			if (ViewActivated != null)
344 				ViewActivated (this, e);
345 		}
346 
347 
348 		[ObsoleteAttribute("CreateComponent has been replaced by CreateInstance")]
CreateComponent(Type componentType)349 		protected internal virtual IComponent CreateComponent (Type componentType)
350 		{
351 			return (this.CreateInstance (componentType)) as IComponent;
352 		}
353 
354 
355 		// XXX: I am not quite sure if this should add the created instance of the component
356 		// to the surface, but it does. (If one finds out that this is wrong just use
357 		// _designerHost.CreateInstance (..)
358 		//
CreateInstance(Type type)359 		protected internal virtual object CreateInstance (Type type)
360 		{
361 			if (type == null)
362 				throw new System.ArgumentNullException ("type");
363 
364 			return _designerHost.CreateComponent (type);
365 		}
366 
367 
CreateDesigner(IComponent component, bool rootDesigner)368 		protected internal virtual IDesigner CreateDesigner (IComponent component, bool rootDesigner)
369 		{
370 			if (component == null)
371 				throw new System.ArgumentNullException ("component");
372 			if (_designerHost == null)
373 				throw new System.ObjectDisposedException ("DesignerSurface");
374 
375 			return _designerHost.CreateDesigner (component, rootDesigner);
376 		}
377 
CreateNestedContainer(IComponent owningComponent)378 		public INestedContainer CreateNestedContainer (IComponent owningComponent)
379 		{
380 			return this.CreateNestedContainer (owningComponent, null);
381 		}
382 
CreateNestedContainer(IComponent owningComponent, string containerName)383 		public INestedContainer CreateNestedContainer (IComponent owningComponent, string containerName)
384 		{
385 			if (_designerHost == null)
386 				throw new ObjectDisposedException ("DesignSurface");
387 
388 			return new DesignModeNestedContainer (owningComponent, containerName);
389 		}
390 
391 
392 #region IServiceProvider
393 
GetService(Type serviceType)394 		public object GetService (Type serviceType)
395 		{
396 			if (typeof (IServiceContainer) == serviceType)
397 				return _serviceContainer;
398 
399 			return _serviceContainer.GetService (serviceType);
400 		}
401 
402 #endregion
403 
404 	}
405 
406 }
407