| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 |
- //
- // System.ComponentModel.Design.DesignerHost
- //
- // Authors:
- // Ivan N. Zlatev (contact i-nZ.net)
- //
- // (C) 2006-2007 Ivan N. Zlatev
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if NET_2_0
- using System;
- using System.Collections;
- using System.ComponentModel;
- using System.ComponentModel.Design.Serialization;
- using System.Windows.Forms.Design;
- using System.Reflection;
- namespace System.ComponentModel.Design
- {
- // A container for components and their designers
- //
- internal sealed class DesignerHost : Container, IDesignerLoaderHost, IDesignerHost, IServiceProvider, IComponentChangeService
- {
- #region DesignerHostTransaction : DesignerTransaction
- private enum TransactionAction
- {
- Commit,
- Cancel
- }
- private sealed class DesignerHostTransaction : DesignerTransaction
- {
-
- DesignerHost _designerHost;
-
- public DesignerHostTransaction (DesignerHost host, string description) : base (description)
- {
- _designerHost = host;
- }
- protected override void OnCancel ()
- {
- _designerHost.OnTransactionClosing (this, TransactionAction.Cancel);
- _designerHost.OnTransactionClosed (this, TransactionAction.Cancel);
- }
-
- protected override void OnCommit ()
- {
- _designerHost.OnTransactionClosing (this, TransactionAction.Commit);
- _designerHost.OnTransactionClosed (this, TransactionAction.Commit);
- }
- } // DesignerHostTransaction
- #endregion
-
- private IServiceProvider _serviceProvider;
- private Hashtable _designers;
- private Stack _transactions;
- private IServiceContainer _serviceContainer;
- private bool _loading;
-
- public DesignerHost (IServiceProvider serviceProvider)
- {
- if (serviceProvider == null)
- throw new ArgumentNullException ("serviceProvider");
- _serviceProvider = serviceProvider;
- _serviceContainer = serviceProvider.GetService (typeof (IServiceContainer)) as IServiceContainer;
- _designers = new Hashtable ();
- _transactions = new Stack ();
- _loading = true;
- }
-
- #region IContainer
- // XXX: More validation here?
- // (e.g: Make use of a potentially existing INameCreationService)
- //
- public override void Add (IComponent component, string name)
- {
- AddPreProcess (component, name);
- base.Add (component, name);
- AddPostProcess (component, name);
- }
- internal void AddPreProcess (IComponent component, string name)
- {
- if (ComponentAdding != null)
- ComponentAdding (this, new ComponentEventArgs (component));
- }
- internal void AddPostProcess (IComponent component, string name)
- {
- IDesigner designer;
- if (_rootComponent == null) {
- _rootComponent = component;
- designer = this.CreateDesigner (component, true);
- }
- else {
- designer = this.CreateDesigner (component, false);
- }
-
- if (designer != null) {
- _designers[component] = designer;
- designer.Initialize (component);
- } else {
- IUIService uiService = GetService (typeof (IUIService)) as IUIService;
- if (uiService != null) {
- uiService.ShowError ("Unable to load a designer for component type '" +
- component.GetType ().Name + "'");
- }
- this.DestroyComponent (component);
- }
- // Activate the host and design surface once the root component is added to
- // the container and its designer is loaded and added to the designers collection
- if (component == _rootComponent)
- this.Activate ();
- if (component is IExtenderProvider) {
- IExtenderProviderService service = this.GetService (typeof (IExtenderProviderService)) as IExtenderProviderService;
- if (service != null)
- service.AddExtenderProvider ((IExtenderProvider) component);
- }
- if (ComponentAdded != null)
- ComponentAdded (this, new ComponentEventArgs (component));
- }
- public override void Remove (IComponent component)
- {
- RemovePreProcess (component);
- base.Remove (component);
- RemovePostProcess (component);
- }
- internal void RemovePreProcess (IComponent component)
- {
- if (ComponentRemoving != null)
- ComponentRemoving (this, new ComponentEventArgs (component));
- IDesigner designer = _designers[component] as IDesigner;
- if (designer != null)
- designer.Dispose ();
- _designers.Remove (component);
- if (component == _rootComponent)
- _rootComponent = null;
- if (component is IExtenderProvider) {
- IExtenderProviderService service = GetService (typeof (IExtenderProviderService)) as IExtenderProviderService;
- if (service != null)
- service.RemoveExtenderProvider ((IExtenderProvider) component);
- }
- }
- internal void RemovePostProcess (IComponent component)
- {
- if (ComponentRemoved != null)
- ComponentRemoved (this, new ComponentEventArgs (component));
- }
- protected override ISite CreateSite (IComponent component, string name)
- {
- if (name == null) {
- INameCreationService nameService = this.GetService (typeof (INameCreationService)) as INameCreationService;
- if (nameService != null)
- name = nameService.CreateName (this, component.GetType ());
- }
- return new DesignModeSite (component, name, this, this);
- }
-
- #endregion
-
- #region IDesignerHost
- private IComponent _rootComponent;
-
- public IContainer Container {
- get { return this; }
- }
- public bool InTransaction {
- get {
- if (_transactions != null && _transactions.Count > 0)
- return true;
- return false;
- }
- }
- public bool Loading {
- get { return _loading; }
- }
- public IComponent RootComponent {
- get { return _rootComponent; }
- }
- public string RootComponentClassName {
- get {
- if (_rootComponent != null)
- return ((object)_rootComponent).GetType ().AssemblyQualifiedName;
- return null;
- }
- }
- public string TransactionDescription {
- get {
- if (_transactions != null && _transactions.Count > 0)
- return ((DesignerHostTransaction) _transactions.Peek()).Description;
-
- return null;
- }
- }
-
- // GUI loading in the designer should be done after the Activated event is raised.
- //
- public void Activate ()
- {
- ISelectionService selectionService = GetService (typeof (ISelectionService)) as ISelectionService;
- // Set the Primary Selection to be the root component
- //
- if (selectionService != null)
- selectionService.SetSelectedComponents (new IComponent[] { _rootComponent });
-
- if (Activated != null)
- Activated (this, EventArgs.Empty);
- }
-
- public IComponent CreateComponent (Type componentClass)
- {
- return CreateComponent (componentClass, null);
- }
- public IComponent CreateComponent (Type componentClass, string name)
- {
- if (componentClass == null)
- throw new ArgumentNullException ("componentClass");
-
- else if (!typeof(IComponent).IsAssignableFrom(componentClass))
- throw new ArgumentException ("componentClass");
- IComponent component = this.CreateInstance (componentClass) as IComponent;
- this.Add (component, name);
-
- return component;
- }
- internal object CreateInstance (Type type)
- {
- if (type == null)
- throw new System.ArgumentNullException ("type");
-
- // FIXME: Should I use TypeDescriptor.CreateInstance() for 2.0 ?
- //
- return Activator.CreateInstance (type, BindingFlags.CreateInstance | BindingFlags.Public
- | BindingFlags.Instance, null, null, null);
- }
- internal IDesigner CreateDesigner (IComponent component, bool rootDesigner)
- {
- if (component == null)
- throw new System.ArgumentNullException ("component");
-
- if (rootDesigner) {
- //return TypeDescriptor.CreateDesigner (component, typeof (IRootDesigner));
- return this.CreateDesigner (component, typeof (IRootDesigner));
- }
- else {
- //return TypeDescriptor.CreateDesigner (component, typeof (IDesigner));
- return this.CreateDesigner (component, typeof (IDesigner));
- }
- }
- // Since most of the specific designers are missing this temporary method
- // will fallback to the first available designer type in the type's base types
- //
- private IDesigner CreateDesigner (IComponent component, Type designerBaseType)
- {
- IDesigner instance = null;
- AttributeCollection attributes = TypeDescriptor.GetAttributes (component);
- foreach (Attribute attribute in attributes) {
- DesignerAttribute designerAttr = attribute as DesignerAttribute;
- if (designerAttr != null &&
- (designerBaseType.FullName == designerAttr.DesignerBaseTypeName ||
- designerBaseType.AssemblyQualifiedName == designerAttr.DesignerBaseTypeName)) {
- Type type = Type.GetType (designerAttr.DesignerTypeName);
- if (type == null && designerBaseType == typeof (IRootDesigner))
- type = typeof (System.Windows.Forms.Design.DocumentDesigner);
- if (type != null)
- instance = (IDesigner) Activator.CreateInstance (type);
- break;
- }
- }
- if (instance == null) {
- Type baseType = component.GetType ().BaseType;
- do {
- attributes = TypeDescriptor.GetAttributes (baseType);
- foreach (Attribute attribute in attributes) {
- DesignerAttribute designerAttr = attribute as DesignerAttribute;
- if (designerAttr != null &&
- (designerBaseType.FullName == designerAttr.DesignerBaseTypeName ||
- designerBaseType.AssemblyQualifiedName == designerAttr.DesignerBaseTypeName)) {
- Type type = Type.GetType (designerAttr.DesignerTypeName);
- if (type != null)
- instance = (IDesigner) Activator.CreateInstance (type);
- break;
- }
- }
- baseType = baseType.BaseType;
- } while (instance == null && baseType != null);
- }
- return instance;
- }
- public void DestroyComponent (IComponent component)
- {
- if (component.Site != null && component.Site.Container == this) {
- OnComponentChanging (component, null);
-
- this.Remove (component); // takes care for the designer as well
- component.Dispose ();
- OnComponentChanged (component, null, null, null);
- }
- }
- public IDesigner GetDesigner (IComponent component)
- {
- if (component == null)
- throw new ArgumentNullException ("component");
-
- return _designers[component] as IDesigner;
- }
- public DesignerTransaction CreateTransaction ()
- {
- return CreateTransaction (null);
- }
-
- public DesignerTransaction CreateTransaction (string description)
- {
- if (TransactionOpening != null)
- TransactionOpening (this, EventArgs.Empty);
-
- DesignerHostTransaction transaction = new DesignerHostTransaction (this, description);
- _transactions.Push (transaction);
- if (TransactionOpened != null)
- TransactionOpened (this, EventArgs.Empty);
-
- return transaction;
- }
- public Type GetType (string typeName)
- {
- Type result;
- ITypeResolutionService s = GetService (typeof (ITypeResolutionService)) as ITypeResolutionService;
-
- if (s != null)
- result = s.GetType (typeName);
- else
- result = Type.GetType (typeName);
-
- return result;
- }
- // Take care of disposing the designer the base.Dispose will cleanup
- // the components.
- //
- protected override void Dispose (bool disposing)
- {
- Unload ();
- base.Dispose (disposing);
- }
-
- public event EventHandler Activated;
- public event EventHandler Deactivated;
- public event EventHandler LoadComplete;
- public event DesignerTransactionCloseEventHandler TransactionClosed;
- public event DesignerTransactionCloseEventHandler TransactionClosing;
- public event EventHandler TransactionOpened;
- public event EventHandler TransactionOpening;
- private void OnTransactionClosing (DesignerHostTransaction raiser, TransactionAction action)
- {
- bool commit = false;
- bool lastTransaction = false;
- if (_transactions.Peek () != raiser)
- throw new InvalidOperationException ("Current transaction differs from the one a commit was requested for.");
- if (_transactions.Count == 1)
- lastTransaction = true;
- if (action == TransactionAction.Commit)
- commit = true;
- if (TransactionClosing != null)
- TransactionClosing (this, new DesignerTransactionCloseEventArgs (commit, lastTransaction));
- }
- private void OnTransactionClosed (DesignerHostTransaction raiser, TransactionAction action)
- {
- bool commit = false;
- bool lastTransaction = false;
- if (_transactions.Peek () != raiser)
- throw new InvalidOperationException ("Current transaction differs from the one a commit was requested for.");
- if (_transactions.Count == 1)
- lastTransaction = true;
- if (action == TransactionAction.Commit)
- commit = true;
- _transactions.Pop ();
- if (TransactionClosed != null)
- TransactionClosed (this, new DesignerTransactionCloseEventArgs (commit, lastTransaction));
- }
-
- #endregion
-
- #region IDesignerLoaderHost
-
- internal event LoadedEventHandler DesignerLoaderHostLoaded;
- internal event EventHandler DesignerLoaderHostLoading;
- internal event EventHandler DesignerLoaderHostUnloading;
- internal event EventHandler DesignerLoaderHostUnloaded;
-
- public void EndLoad (string rootClassName, bool successful, ICollection errorCollection)
- {
- if (DesignerLoaderHostLoaded != null)
- DesignerLoaderHostLoaded (this, new LoadedEventArgs (successful, errorCollection));
-
- if (LoadComplete != null)
- LoadComplete (this, EventArgs.Empty);
- _loading = false; // _loading = true is set by the ctor
- }
- // BasicDesignerLoader invokes this.Reload, then invokes BeginLoad on itself,
- // then when loading it the loader is done it ends up in this.EndLoad.
- // At the end of the day Reload is more like Unload.
- //
- public void Reload ()
- {
- _loading = true;
- Unload ();
- if (DesignerLoaderHostLoading != null)
- DesignerLoaderHostLoading (this, EventArgs.Empty);
- }
- private void Unload ()
- {
- if (DesignerLoaderHostUnloading != null)
- DesignerLoaderHostUnloading (this, EventArgs.Empty);
- IComponent[] components = new IComponent[this.Components.Count];
- this.Components.CopyTo (components, 0);
-
- foreach (IComponent component in components)
- this.Remove (component);
- _transactions.Clear ();
-
- if (DesignerLoaderHostUnloaded != null)
- DesignerLoaderHostUnloaded (this, EventArgs.Empty);
- }
-
- #endregion
- #region IComponentChangeService
-
- public event ComponentEventHandler ComponentAdded;
- public event ComponentEventHandler ComponentAdding;
- public event ComponentChangedEventHandler ComponentChanged;
- public event ComponentChangingEventHandler ComponentChanging;
- public event ComponentEventHandler ComponentRemoved;
- public event ComponentEventHandler ComponentRemoving;
- public event ComponentRenameEventHandler ComponentRename;
-
-
- public void OnComponentChanged (object component, MemberDescriptor member, object oldValue, object newValue)
- {
- if (ComponentChanged != null)
- ComponentChanged (this, new ComponentChangedEventArgs (component, member, oldValue, newValue));
- }
-
- public void OnComponentChanging (object component, MemberDescriptor member)
- {
- if (ComponentChanging != null)
- ComponentChanging (this, new ComponentChangingEventArgs (component, member));
- }
- internal void OnComponentRename (object component, string oldName, string newName)
- {
- if (ComponentRename != null)
- ComponentRename (this, new ComponentRenameEventArgs (component, oldName, newName));
- }
-
- #endregion
-
- #region IServiceContainer
- // Wrapper around the DesignSurface service container
- //
- public void AddService (Type serviceType, object serviceInstance)
- {
- _serviceContainer.AddService (serviceType, serviceInstance);
- }
-
- public void AddService (Type serviceType, object serviceInstance, bool promote)
- {
- _serviceContainer.AddService (serviceType, serviceInstance, promote);
- }
-
- public void AddService (Type serviceType, ServiceCreatorCallback callback)
- {
- _serviceContainer.AddService (serviceType, callback);
- }
- public void AddService (Type serviceType, ServiceCreatorCallback callback, bool promote)
- {
- _serviceContainer.AddService (serviceType, callback, promote);
- }
- public void RemoveService (Type serviceType)
- {
- _serviceContainer.RemoveService (serviceType);
- }
- public void RemoveService (Type serviceType, bool promote)
- {
- _serviceContainer.RemoveService (serviceType, promote);
- }
-
- #endregion
- #region IServiceProvider
- public new object GetService (Type serviceType)
- {
- if (_serviceProvider != null)
- return _serviceProvider.GetService (serviceType);
- return null;
- }
-
- #endregion
-
- }
- }
- #endif
|