3c1f479b9d
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
250 lines
8.2 KiB
C#
250 lines
8.2 KiB
C#
//
|
|
// System.ComponentModel.Design.DesignSurfaceManager
|
|
//
|
|
// Authors:
|
|
// Ivan N. Zlatev (contact i-nZ.net)
|
|
//
|
|
// (C) 2006 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.
|
|
//
|
|
|
|
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Collections;
|
|
|
|
namespace System.ComponentModel.Design
|
|
{
|
|
|
|
public class DesignSurfaceManager : IServiceProvider, IDisposable
|
|
{
|
|
|
|
private class MergedServiceProvider : IServiceProvider
|
|
{
|
|
private IServiceProvider _primaryProvider;
|
|
private IServiceProvider _secondaryProvider;
|
|
|
|
public MergedServiceProvider (IServiceProvider primary, IServiceProvider secondary)
|
|
{
|
|
if (primary == null)
|
|
throw new ArgumentNullException ("primary");
|
|
if (secondary == null)
|
|
throw new ArgumentNullException ("secondary");
|
|
|
|
_primaryProvider = primary;
|
|
_secondaryProvider = secondary;
|
|
}
|
|
|
|
public object GetService (Type service)
|
|
{
|
|
object result = _primaryProvider.GetService (service);
|
|
if (result == null)
|
|
result = _secondaryProvider.GetService (service);
|
|
|
|
return result;
|
|
}
|
|
|
|
} // MergedServiceProvider
|
|
|
|
|
|
private IServiceProvider _parentProvider;
|
|
private ServiceContainer _serviceContainer;
|
|
|
|
public DesignSurfaceManager () : this (null)
|
|
{
|
|
}
|
|
|
|
public DesignSurfaceManager (IServiceProvider serviceProvider)
|
|
{
|
|
_parentProvider = serviceProvider;
|
|
this.ServiceContainer.AddService (typeof (IDesignerEventService), new DesignerEventService ());
|
|
}
|
|
|
|
// The CreateDesignSurfaceCore method is called by both CreateDesignSurface methods.
|
|
// It is the implementation that actually creates the design surface. The default
|
|
// implementation just returns a new DesignSurface. You may override this method to provide
|
|
// a custom object that derives from the DesignSurface class.
|
|
//
|
|
protected virtual DesignSurface CreateDesignSurfaceCore (IServiceProvider parentProvider)
|
|
{
|
|
DesignSurface surface = new DesignSurface (parentProvider);
|
|
OnDesignSurfaceCreated (surface);
|
|
return surface;
|
|
}
|
|
|
|
public DesignSurface CreateDesignSurface ()
|
|
{
|
|
return CreateDesignSurfaceCore (this);
|
|
}
|
|
|
|
// MSDN: parentProvider - A parent service provider. A new merged service provider will be created that
|
|
// will first ask this provider for a service, and then delegate any failures to the design surface
|
|
// manager object. This merged provider will be passed into the CreateDesignSurfaceCore method.
|
|
//
|
|
public DesignSurface CreateDesignSurface (IServiceProvider parentProvider)
|
|
{
|
|
if (parentProvider == null)
|
|
throw new ArgumentNullException ("parentProvider");
|
|
|
|
return CreateDesignSurfaceCore (new MergedServiceProvider (parentProvider, this));
|
|
}
|
|
|
|
public virtual DesignSurface ActiveDesignSurface {
|
|
get {
|
|
DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService;
|
|
if (eventService != null) {
|
|
IDesignerHost designer = eventService.ActiveDesigner;
|
|
if (designer != null)
|
|
return designer.GetService (typeof (DesignSurface)) as DesignSurface;
|
|
}
|
|
return null;
|
|
}
|
|
set {
|
|
if (value != null) {
|
|
DesignSurface oldSurface = null;
|
|
|
|
// get current surface
|
|
DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService;
|
|
if (eventService != null) {
|
|
IDesignerHost designer = eventService.ActiveDesigner;
|
|
if (designer != null)
|
|
oldSurface = designer.GetService (typeof (DesignSurface)) as DesignSurface;
|
|
}
|
|
|
|
ISelectionService selectionService = null;
|
|
|
|
if (oldSurface != value) {
|
|
// unsubscribe from current's selectionchanged
|
|
if (oldSurface != null) {
|
|
selectionService = oldSurface.GetService (typeof (ISelectionService)) as ISelectionService;
|
|
if (selectionService != null)
|
|
selectionService.SelectionChanged -= new EventHandler (OnSelectionChanged);
|
|
}
|
|
// subscribe to new's selectionchanged
|
|
selectionService = value.GetService (typeof (ISelectionService)) as ISelectionService;
|
|
if (selectionService != null)
|
|
selectionService.SelectionChanged += new EventHandler (OnSelectionChanged);
|
|
|
|
// set it
|
|
eventService.ActiveDesigner = value.GetService (typeof (IDesignerHost)) as IDesignerHost;
|
|
|
|
// fire event
|
|
if (this.ActiveDesignSurfaceChanged != null)
|
|
this.ActiveDesignSurfaceChanged (this, new ActiveDesignSurfaceChangedEventArgs (oldSurface, value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public DesignSurfaceCollection DesignSurfaces {
|
|
get {
|
|
DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService;
|
|
if (eventService != null)
|
|
return new DesignSurfaceCollection (eventService.Designers);
|
|
|
|
return new DesignSurfaceCollection (null);
|
|
}
|
|
}
|
|
|
|
protected ServiceContainer ServiceContainer {
|
|
get {
|
|
if (_serviceContainer == null)
|
|
_serviceContainer = new ServiceContainer (_parentProvider);
|
|
|
|
return _serviceContainer;
|
|
}
|
|
}
|
|
|
|
// MSDN2 says those events are mapped through the IDesignerEventService,
|
|
// but I preferd not to do that. Should not cause compitability issues.
|
|
//
|
|
//
|
|
// The SelectionChanged is fired only for a changed component selection on the
|
|
// active designersurface.
|
|
//
|
|
public event EventHandler SelectionChanged;
|
|
public event DesignSurfaceEventHandler DesignSurfaceDisposed;
|
|
public event DesignSurfaceEventHandler DesignSurfaceCreated;
|
|
public event ActiveDesignSurfaceChangedEventHandler ActiveDesignSurfaceChanged;
|
|
|
|
private void OnSelectionChanged (object sender, EventArgs args)
|
|
{
|
|
if (SelectionChanged != null)
|
|
SelectionChanged (this, EventArgs.Empty);
|
|
|
|
DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService;
|
|
if (eventService != null)
|
|
eventService.RaiseSelectionChanged ();
|
|
}
|
|
|
|
private void OnDesignSurfaceCreated (DesignSurface surface)
|
|
{
|
|
if (DesignSurfaceCreated != null)
|
|
DesignSurfaceCreated (this, new DesignSurfaceEventArgs (surface));
|
|
|
|
// monitor disposing
|
|
surface.Disposed += new EventHandler (OnDesignSurfaceDisposed);
|
|
|
|
DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService;
|
|
if (eventService != null)
|
|
eventService.RaiseDesignerCreated (surface.GetService (typeof (IDesignerHost)) as IDesignerHost);
|
|
}
|
|
|
|
private void OnDesignSurfaceDisposed (object sender, EventArgs args)
|
|
{
|
|
DesignSurface surface = (DesignSurface) sender;
|
|
|
|
surface.Disposed -= new EventHandler (OnDesignSurfaceDisposed);
|
|
|
|
if (DesignSurfaceDisposed != null)
|
|
DesignSurfaceDisposed (this, new DesignSurfaceEventArgs (surface));
|
|
|
|
DesignerEventService eventService = GetService (typeof (IDesignerEventService)) as DesignerEventService;
|
|
if (eventService != null)
|
|
eventService.RaiseDesignerDisposed (surface.GetService (typeof (IDesignerHost)) as IDesignerHost);
|
|
|
|
}
|
|
|
|
public object GetService (Type service)
|
|
{
|
|
if (_serviceContainer != null)
|
|
return _serviceContainer.GetService (service);
|
|
|
|
return null;
|
|
}
|
|
|
|
public void Dispose ()
|
|
{
|
|
Dispose (true);
|
|
}
|
|
|
|
protected virtual void Dispose (bool disposing)
|
|
{
|
|
if (disposing && _serviceContainer != null) {
|
|
_serviceContainer.Dispose ();
|
|
_serviceContainer = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|