781 lines
24 KiB
C#
781 lines
24 KiB
C#
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.Design;
|
|
using System.ComponentModel.Design.Serialization;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
|
|
using ICSharpCode.Core;
|
|
using ICSharpCode.FormsDesigner.Services;
|
|
using ICSharpCode.FormsDesigner.UndoRedo;
|
|
using ICSharpCode.SharpDevelop;
|
|
using ICSharpCode.SharpDevelop.Dom;
|
|
using ICSharpCode.SharpDevelop.Editor;
|
|
using ICSharpCode.SharpDevelop.Gui;
|
|
using ICSharpCode.SharpDevelop.Refactoring;
|
|
namespace ICSharpCode.FormsDesigner
|
|
{
|
|
public class FormsDesignerViewContent : IDisposable, IServiceProvider, IClipboardHandler, IUndoHandler, IHasPropertyContainer, IContextHelpProvider, IToolsHost
|
|
{
|
|
DesignSurface designSurface;
|
|
bool disposing;
|
|
|
|
DesignerLoader loader;
|
|
FormsDesignerUndoEngine undoEngine;
|
|
DesignerResourceService designerResourceService;
|
|
TypeResolutionService typeResolutionService;
|
|
string generatedCode = null;
|
|
VisualPascalABC.CodeFileDocumentControl codeFileDocument; //roman//
|
|
public delegate void ModifyDelegate();
|
|
public ModifyDelegate Modify;
|
|
|
|
|
|
//roman//
|
|
static FormsDesignerViewContent()
|
|
{
|
|
ICSharpCode.Core.WinForms.WinFormsResourceService.AddToBitmapCache("Icons.16x16.SideBarDocument", global::VisualPascalABC.Properties.Resources.Pointer);
|
|
}
|
|
|
|
private void PropertyPadEditorKeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
if (PropertyPad.Grid.SelectedGridItem.Label == "(Name)")
|
|
{
|
|
if (e.KeyChar == (char)Keys.Back || isNameValid((string)PropertyPad.Grid.SelectedGridItem.Value + e.KeyChar))
|
|
{
|
|
e.Handled = false;
|
|
}
|
|
else
|
|
e.Handled = true;
|
|
}
|
|
else
|
|
e.Handled = false;
|
|
}
|
|
|
|
private static bool isNameValid(string name)
|
|
{
|
|
if (name == null)
|
|
return false;
|
|
if (name.Length == 0)
|
|
return false;
|
|
if (!(name[0] == '_' || (name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')))
|
|
return false;
|
|
for (int i = 1; i < name.Length; i++)
|
|
if (!(name[i] == '_' || (name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') || char.IsDigit(name[i])))
|
|
return false;
|
|
return true;
|
|
}
|
|
//roman//
|
|
|
|
|
|
|
|
|
|
public System.CodeDom.CodeCompileUnit CodeCompileUnit
|
|
{
|
|
get
|
|
{
|
|
return (loader as CodeDomHostLoader).GetCodeCompileUnit();
|
|
}
|
|
}
|
|
public string FileName
|
|
{
|
|
get
|
|
{
|
|
return codeFileDocument.FileName;
|
|
}
|
|
}
|
|
|
|
public void ResetGeneratedCode()
|
|
{
|
|
generatedCode = null;
|
|
}
|
|
|
|
public string GeneratedCode
|
|
{
|
|
get
|
|
{
|
|
generatedCode = (loader as CodeDomHostLoader).GetCode();
|
|
return generatedCode;
|
|
}
|
|
}
|
|
|
|
private bool isDirty;
|
|
public bool IsDirty
|
|
{
|
|
get
|
|
{
|
|
return isDirty;
|
|
}
|
|
set
|
|
{
|
|
isDirty = value;
|
|
if (value && Modify != null) Modify();
|
|
}
|
|
}
|
|
|
|
public DesignSurface DesignSurface {
|
|
get {
|
|
return designSurface;
|
|
}
|
|
}
|
|
|
|
public static SharpDevelopSideBar FormsDesignerToolBox
|
|
{
|
|
get
|
|
{
|
|
return ToolboxProvider.FormsDesignerSideBar;
|
|
}
|
|
}
|
|
|
|
public static PropertyPad PropertyPad
|
|
{
|
|
get
|
|
{
|
|
return PropertyContainer.PropertyPad;
|
|
}
|
|
}
|
|
|
|
public IDesignerHost Host {
|
|
get {
|
|
if (designSurface == null)
|
|
return null;
|
|
return (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
|
|
}
|
|
}
|
|
|
|
public FormsDesignerViewContent(VisualPascalABC.CodeFileDocumentControl documentControl) //roman//
|
|
: base()
|
|
{
|
|
if (documentControl == null)
|
|
throw new ArgumentNullException("documentControl");
|
|
this.codeFileDocument = documentControl;
|
|
if (!FormKeyHandler.inserted) {
|
|
FormKeyHandler.Insert();
|
|
}
|
|
}
|
|
|
|
bool inMasterLoadOperation;
|
|
|
|
public void LoadDesigner(string formFile)
|
|
{
|
|
UnloadDesigner();
|
|
DefaultServiceContainer serviceContainer = new DefaultServiceContainer();
|
|
serviceContainer.AddService(typeof(System.Windows.Forms.Design.IUIService), new UIService());
|
|
serviceContainer.AddService(typeof(System.Drawing.Design.IToolboxService), ToolboxProvider.ToolboxService);
|
|
|
|
serviceContainer.AddService(typeof(IHelpService), new HelpService());
|
|
serviceContainer.AddService(typeof(System.Drawing.Design.IPropertyValueUIService), new PropertyValueUIService());
|
|
|
|
AmbientProperties ambientProperties = new AmbientProperties();
|
|
serviceContainer.AddService(typeof(AmbientProperties), ambientProperties);
|
|
this.typeResolutionService = new TypeResolutionService();
|
|
serviceContainer.AddService(typeof(ITypeResolutionService), this.typeResolutionService);
|
|
serviceContainer.AddService(typeof(DesignerOptionService), new SharpDevelopDesignerOptionService());
|
|
serviceContainer.AddService(typeof(ITypeDiscoveryService), new TypeDiscoveryService());
|
|
serviceContainer.AddService(typeof(MemberRelationshipService), new DefaultMemberRelationshipService());
|
|
|
|
designSurface = CreateDesignSurface(serviceContainer);
|
|
designSurface.Loading += this.DesignerLoading;
|
|
designSurface.Loaded += this.DesignerLoaded;
|
|
designSurface.Flushed += this.DesignerFlushed;
|
|
designSurface.Unloading += this.DesignerUnloading;
|
|
|
|
designerResourceService = new DesignerResourceService(this);//roman//
|
|
serviceContainer.AddService(typeof(System.ComponentModel.Design.IResourceService), designerResourceService);
|
|
loader = new CodeDomHostLoader(this.Host, formFile, FileName);
|
|
|
|
serviceContainer.AddService(typeof(System.ComponentModel.Design.IMenuCommandService), new ICSharpCode.FormsDesigner.Services.MenuCommandService(Host));
|
|
ICSharpCode.FormsDesigner.Services.EventBindingService eventBindingService = new ICSharpCode.FormsDesigner.Services.EventBindingService(Host);
|
|
serviceContainer.AddService(typeof(System.ComponentModel.Design.IEventBindingService), eventBindingService);
|
|
|
|
designSurface.BeginLoad(loader);
|
|
|
|
if (!designSurface.IsLoaded) {
|
|
throw new FormsDesignerLoadException(FormatLoadErrors(designSurface));
|
|
}
|
|
|
|
undoEngine = new FormsDesignerUndoEngine(Host);
|
|
serviceContainer.AddService(typeof(UndoEngine), undoEngine);
|
|
|
|
IComponentChangeService componentChangeService = (IComponentChangeService)designSurface.GetService(typeof(IComponentChangeService));
|
|
componentChangeService.ComponentChanged += ComponentChanged;
|
|
componentChangeService.ComponentAdded += ComponentListChanged;
|
|
componentChangeService.ComponentRemoved += ComponentListChanged;
|
|
componentChangeService.ComponentRename += ComponentListChanged;
|
|
this.Host.TransactionClosed += TransactionClose;
|
|
|
|
ISelectionService selectionService = (ISelectionService)designSurface.GetService(typeof(ISelectionService));
|
|
selectionService.SelectionChanged += SelectionChangedHandler;
|
|
|
|
if (IsTabOrderMode) { // fixes SD2-1015
|
|
tabOrderMode = false; // let ShowTabOrder call the designer command again
|
|
ShowTabOrder();
|
|
}
|
|
|
|
UpdatePropertyPad();
|
|
|
|
hasUnmergedChanges = false;
|
|
MakeDirty();
|
|
|
|
PropertyGrid grid = PropertyPad.Grid;
|
|
|
|
var gridView = (Control)grid.GetType().GetField("gridView", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(grid);
|
|
var edit = (Control)gridView.GetType().GetField("edit", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(gridView);
|
|
edit.KeyPress += PropertyPadEditorKeyPress;
|
|
edit.ContextMenu = new ContextMenu();
|
|
}
|
|
//roman//
|
|
public void SaveResources()
|
|
{
|
|
if (designerResourceService != null)
|
|
{
|
|
designerResourceService.Save();
|
|
}
|
|
}
|
|
//roman//
|
|
|
|
bool hasUnmergedChanges;
|
|
|
|
void MakeDirty()
|
|
{
|
|
hasUnmergedChanges = true;
|
|
IsDirty = true;
|
|
//System.Windows.Input.CommandManager.InvalidateRequerySuggested();
|
|
}
|
|
|
|
bool shouldUpdateSelectableObjects = false;
|
|
|
|
void TransactionClose(object sender, DesignerTransactionCloseEventArgs e)
|
|
{
|
|
if (shouldUpdateSelectableObjects) {
|
|
// update the property pad after the transaction is *really* finished
|
|
// (including updating the selection)
|
|
//roman//WorkbenchSingleton.SafeThreadAsyncCall(UpdatePropertyPad);
|
|
VisualPascalABC.VisualPABCSingleton.MainForm.BeginInvoke((Action)UpdatePropertyPad, new object[0]);//roman//
|
|
shouldUpdateSelectableObjects = false;
|
|
}
|
|
VisualPascalABC.VisualPABCSingleton.MainForm.UpdateUndoRedoEnabled();
|
|
}
|
|
|
|
void ComponentChanged(object sender, ComponentChangedEventArgs e)
|
|
{
|
|
bool loading = this.loader != null && this.loader.Loading;
|
|
if (!loading && !unloading) {
|
|
try {
|
|
this.MakeDirty();
|
|
} catch (Exception ex) {
|
|
MessageService.ShowException(ex);
|
|
}
|
|
}
|
|
VisualPascalABC.VisualPABCSingleton.MainForm.UpdateUndoRedoEnabled();
|
|
}
|
|
|
|
void ComponentListChanged(object sender, EventArgs e)
|
|
{
|
|
bool loading = this.loader != null && this.loader.Loading;
|
|
if (!loading && !unloading) {
|
|
shouldUpdateSelectableObjects = true;
|
|
this.MakeDirty();
|
|
}
|
|
VisualPascalABC.VisualPABCSingleton.MainForm.UpdateUndoRedoEnabled();
|
|
}
|
|
|
|
public void UnloadDesigner()
|
|
{
|
|
designSurfaceManager.ActiveDesignSurface = null;
|
|
|
|
if (designSurface != null) {
|
|
designSurface.Loading -= this.DesignerLoading;
|
|
designSurface.Loaded -= this.DesignerLoaded;
|
|
designSurface.Flushed -= this.DesignerFlushed;
|
|
designSurface.Unloading -= this.DesignerUnloading;
|
|
|
|
IComponentChangeService componentChangeService = designSurface.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
|
|
if (componentChangeService != null) {
|
|
componentChangeService.ComponentChanged -= ComponentChanged;
|
|
componentChangeService.ComponentAdded -= ComponentListChanged;
|
|
componentChangeService.ComponentRemoved -= ComponentListChanged;
|
|
componentChangeService.ComponentRename -= ComponentListChanged;
|
|
}
|
|
if (this.Host != null) {
|
|
this.Host.TransactionClosed -= TransactionClose;
|
|
}
|
|
|
|
ISelectionService selectionService = designSurface.GetService(typeof(ISelectionService)) as ISelectionService;
|
|
if (selectionService != null) {
|
|
selectionService.SelectionChanged -= SelectionChangedHandler;
|
|
}
|
|
|
|
designSurface.Unloaded += delegate {
|
|
ServiceContainer serviceContainer = designSurface.GetService(typeof(ServiceContainer)) as ServiceContainer;
|
|
if (serviceContainer != null) {
|
|
// Workaround for .NET bug: .NET unregisters the designer host only if no component throws an exception,
|
|
// but then in a finally block assumes that the designer host is already unloaded.
|
|
// Thus we would get the confusing "InvalidOperationException: The container cannot be disposed at design time"
|
|
// when any component throws an exception.
|
|
|
|
// See http://community.sharpdevelop.net/forums/p/10928/35288.aspx
|
|
// Reproducible with a custom control that has a designer that crashes on unloading
|
|
// e.g. http://www.codeproject.com/KB/toolbars/WinFormsRibbon.aspx
|
|
|
|
// We work around this problem by unregistering the designer host manually.
|
|
try {
|
|
var services = (Dictionary<Type, object>)typeof(ServiceContainer).InvokeMember(
|
|
"Services",
|
|
BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic,
|
|
null, serviceContainer, null);
|
|
foreach (var pair in services.ToArray()) {
|
|
if (pair.Value is IDesignerHost) {
|
|
serviceContainer.GetType().InvokeMember(
|
|
"RemoveFixedService",
|
|
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic,
|
|
null, serviceContainer, new object[] { pair.Key });
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
LoggingService.Error(ex);
|
|
}
|
|
}
|
|
};
|
|
try {
|
|
designSurface.Dispose();
|
|
} catch (ExceptionCollection exceptions) {
|
|
foreach (Exception ex in exceptions.Exceptions) {
|
|
LoggingService.Error(ex);
|
|
}
|
|
} finally {
|
|
designSurface = null;
|
|
}
|
|
}
|
|
|
|
this.typeResolutionService = null;
|
|
this.loader = null;
|
|
}
|
|
|
|
readonly PropertyContainer propertyContainer = new PropertyContainer();
|
|
|
|
public PropertyContainer PropertyContainer {
|
|
get {
|
|
return propertyContainer;
|
|
}
|
|
}
|
|
|
|
public void ShowHelp()
|
|
{
|
|
if (Host == null) {
|
|
return;
|
|
}
|
|
|
|
ISelectionService selectionService = (ISelectionService)Host.GetService(typeof(ISelectionService));
|
|
if (selectionService != null) {
|
|
Control ctl = selectionService.PrimarySelection as Control;
|
|
if (ctl != null) {
|
|
ICSharpCode.SharpDevelop.HelpProvider.ShowHelp(ctl.GetType().FullName);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void LoadAndDisplayDesigner(string formFile)
|
|
{
|
|
try {
|
|
|
|
LoadDesigner(formFile);
|
|
|
|
} catch (Exception e) {
|
|
|
|
if (e.InnerException is FormsDesignerLoadException) {
|
|
throw new FormsDesignerLoadException(e.InnerException.Message, e);
|
|
} else if (e is FormsDesignerLoadException) {
|
|
throw;
|
|
} else if (designSurface != null && !designSurface.IsLoaded && designSurface.LoadErrors != null) {
|
|
throw new FormsDesignerLoadException(FormatLoadErrors(designSurface), e);
|
|
} else {
|
|
throw;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void DesignerLoading(object sender, EventArgs e)
|
|
{
|
|
this.reloadPending = false;
|
|
this.unloading = false;
|
|
}
|
|
|
|
void DesignerUnloading(object sender, EventArgs e)
|
|
{
|
|
this.unloading = true;
|
|
}
|
|
|
|
bool reloadPending;
|
|
bool unloading;
|
|
|
|
void DesignerLoaded(object sender, LoadedEventArgs e)
|
|
{
|
|
// This method is called when the designer has loaded.
|
|
this.reloadPending = false;
|
|
this.unloading = false;
|
|
|
|
if (e.HasSucceeded) {
|
|
// Display the designer on the view content
|
|
Control designView = (Control)this.designSurface.View;
|
|
|
|
designView.BackColor = Color.White;
|
|
designView.RightToLeft = RightToLeft.No;
|
|
// Make sure auto-scaling is based on the correct font.
|
|
// This is required on Vista, I don't know why it works correctly in XP
|
|
designView.Font = System.Windows.Forms.Control.DefaultFont;
|
|
|
|
MakeDirty();
|
|
designSurfaceManager.ActiveDesignSurface = this.designSurface;
|
|
this.UserContent = designView;
|
|
this.UpdatePropertyPad();
|
|
} else {
|
|
// This method can not only be called during initialization,
|
|
// but also when the designer reloads itself because of
|
|
// a language change.
|
|
// When a load error occurs there, we are not somewhere
|
|
// below the Load method which handles load errors.
|
|
// That is why we create an error text box here anyway.
|
|
}
|
|
}
|
|
|
|
void DesignerFlushed(object sender, EventArgs e)
|
|
{
|
|
this.hasUnmergedChanges = false;
|
|
IsDirty = false;
|
|
SaveResources();
|
|
}
|
|
|
|
static string FormatLoadErrors(DesignSurface designSurface)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
foreach(Exception le in designSurface.LoadErrors) {
|
|
sb.AppendLine(le.ToString());
|
|
sb.AppendLine();
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
public virtual void MergeFormChanges()
|
|
{
|
|
designSurface.Flush();
|
|
hasUnmergedChanges = false;
|
|
}
|
|
|
|
public void ShowSourceCode()
|
|
{
|
|
//roman// this.WorkbenchWindow.ActiveViewContent = this.PrimaryViewContent;
|
|
}
|
|
|
|
void IsActiveViewContentChangedHandler(object sender, EventArgs e)
|
|
{
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
disposing = true;
|
|
try {
|
|
// base.Dispose() is called first because it may trigger a call
|
|
// to SaveInternal which requires the designer to be loaded.
|
|
//roman// base.Dispose();
|
|
} finally {
|
|
this.UnloadDesigner();
|
|
}
|
|
}
|
|
|
|
void SelectionChangedHandler(object sender, EventArgs args)
|
|
{
|
|
UpdatePropertyPadSelection((ISelectionService)sender);
|
|
}
|
|
|
|
void UpdatePropertyPadSelection(ISelectionService selectionService)
|
|
{
|
|
ICollection selection = selectionService.GetSelectedComponents();
|
|
object[] selArray = new object[selection.Count];
|
|
selection.CopyTo(selArray, 0);
|
|
propertyContainer.SelectedObjects = selArray;
|
|
//System.Windows.Input.CommandManager.InvalidateRequerySuggested();
|
|
}
|
|
|
|
protected void UpdatePropertyPad()
|
|
{
|
|
if (Host != null) {
|
|
propertyContainer.Host = Host;
|
|
propertyContainer.SelectableObjects = Host.Container.Components;
|
|
ISelectionService selectionService = (ISelectionService)Host.GetService(typeof(ISelectionService));
|
|
if (selectionService != null) {
|
|
UpdatePropertyPadSelection(selectionService);
|
|
}
|
|
}
|
|
}
|
|
|
|
Control userContent;
|
|
|
|
public Control UserContent
|
|
{
|
|
get
|
|
{
|
|
/*SDWindowsFormsHost host = userContent as SDWindowsFormsHost;
|
|
return host != null ? host.Child : null;*/
|
|
//roman//
|
|
return userContent;
|
|
}
|
|
set
|
|
{
|
|
/*SDWindowsFormsHost host = userContent as SDWindowsFormsHost;
|
|
if (value == null)
|
|
{
|
|
userContent = null;
|
|
if (host != null)
|
|
host.Dispose();
|
|
return;
|
|
}
|
|
if (host != null)
|
|
{
|
|
if (host.IsDisposed)
|
|
{
|
|
host = null;
|
|
}
|
|
else if (host.Child == value)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
if (host == null)
|
|
{
|
|
host = new SDWindowsFormsHost(true);
|
|
host.ServiceObject = this;
|
|
host.DisposeChild = false;
|
|
}
|
|
host.Child = value;
|
|
userContent = host;*/
|
|
|
|
userContent = value;
|
|
}
|
|
}
|
|
|
|
#region IUndoHandler implementation
|
|
public bool EnableUndo {
|
|
get {
|
|
if (undoEngine != null) {
|
|
return undoEngine.EnableUndo;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
public bool EnableRedo {
|
|
get {
|
|
if (undoEngine != null) {
|
|
return undoEngine.EnableRedo;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public virtual void Undo()
|
|
{
|
|
if (undoEngine != null) {
|
|
undoEngine.Undo();
|
|
}
|
|
}
|
|
|
|
public virtual void Redo()
|
|
{
|
|
if (undoEngine != null) {
|
|
undoEngine.Redo();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region IClipboardHandler implementation
|
|
bool IsMenuCommandEnabled(CommandID commandID)
|
|
{
|
|
if (designSurface == null) {
|
|
return false;
|
|
}
|
|
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
if (menuCommandService == null) {
|
|
return false;
|
|
}
|
|
|
|
System.ComponentModel.Design.MenuCommand menuCommand = menuCommandService.FindCommand(commandID);
|
|
if (menuCommand == null) {
|
|
return false;
|
|
}
|
|
|
|
//int status = menuCommand.OleStatus;
|
|
return menuCommand.Enabled;
|
|
}
|
|
|
|
public bool EnableCut {
|
|
get {
|
|
return IsMenuCommandEnabled(StandardCommands.Cut);
|
|
}
|
|
}
|
|
|
|
public bool EnableCopy {
|
|
get {
|
|
return IsMenuCommandEnabled(StandardCommands.Copy);
|
|
}
|
|
}
|
|
|
|
const string ComponentClipboardFormat = "CF_DESIGNERCOMPONENTS";
|
|
public bool EnablePaste {
|
|
get {
|
|
return IsMenuCommandEnabled(StandardCommands.Paste);
|
|
}
|
|
}
|
|
|
|
public bool EnableDelete {
|
|
get {
|
|
return IsMenuCommandEnabled(StandardCommands.Delete);
|
|
}
|
|
}
|
|
|
|
public bool EnableSelectAll {
|
|
get {
|
|
return designSurface != null;
|
|
}
|
|
}
|
|
|
|
public void Cut()
|
|
{
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
menuCommandService.GlobalInvoke(StandardCommands.Cut);
|
|
}
|
|
|
|
public void Copy()
|
|
{
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
menuCommandService.GlobalInvoke(StandardCommands.Copy);
|
|
}
|
|
|
|
public void Paste()
|
|
{
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
menuCommandService.GlobalInvoke(StandardCommands.Paste);
|
|
}
|
|
|
|
public void Delete()
|
|
{
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
menuCommandService.GlobalInvoke(StandardCommands.Delete);
|
|
}
|
|
|
|
public void SelectAll()
|
|
{
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
menuCommandService.GlobalInvoke(StandardCommands.SelectAll);
|
|
}
|
|
#endregion
|
|
|
|
#region Tab Order Handling
|
|
bool tabOrderMode = false;
|
|
public virtual bool IsTabOrderMode {
|
|
get {
|
|
return tabOrderMode;
|
|
}
|
|
}
|
|
|
|
public virtual void ShowTabOrder()
|
|
{
|
|
if (!IsTabOrderMode) {
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
menuCommandService.GlobalInvoke(StandardCommands.TabOrder);
|
|
tabOrderMode = true;
|
|
}
|
|
}
|
|
|
|
public virtual void HideTabOrder()
|
|
{
|
|
if (IsTabOrderMode) {
|
|
IMenuCommandService menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService));
|
|
menuCommandService.GlobalInvoke(StandardCommands.TabOrder);
|
|
tabOrderMode = false;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
protected void MergeAndUnloadDesigner()
|
|
{
|
|
propertyContainer.Clear();
|
|
MergeFormChanges();
|
|
UnloadDesigner();
|
|
}
|
|
|
|
public void ExecuteCommand(CommandID id)
|
|
{
|
|
IServiceContainer sc = Host as IServiceContainer;
|
|
IMenuCommandService mcs = sc.GetService(typeof(IMenuCommandService)) as IMenuCommandService;
|
|
mcs.GlobalInvoke(id);
|
|
}
|
|
|
|
public virtual object ToolsContent {
|
|
get { return ToolboxProvider.FormsDesignerSideBar; }
|
|
}
|
|
|
|
#region Design surface manager (static)
|
|
|
|
static readonly DesignSurfaceManager designSurfaceManager = new DesignSurfaceManager();
|
|
|
|
public static DesignSurface CreateDesignSurface(IServiceProvider serviceProvider)
|
|
{
|
|
return designSurfaceManager.CreateDesignSurface(serviceProvider);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Debugger event handling (to prevent designer reload while debugger is starting)
|
|
|
|
void DebugStarting(object sender, EventArgs e)
|
|
{
|
|
if (designSurfaceManager.ActiveDesignSurface != this.DesignSurface ||
|
|
!this.reloadPending)
|
|
return;
|
|
|
|
// The designer loader does not reload immediately,
|
|
// but only when the Application.Idle event is raised.
|
|
// When the IsActiveViewContentChangedHandler has been called because of the
|
|
// layout change prior to starting the debugger, and it has
|
|
// initiated a reload because of a changed referenced assembly,
|
|
// the reload can interrupt the starting of the debugger.
|
|
// To prevent this, we explicitly raise the Idle event here.
|
|
LoggingService.Debug("Forms designer: DebugStarting raises the Idle event to force pending reload now");
|
|
Cursor oldCursor = Cursor.Current;
|
|
Cursor.Current = Cursors.WaitCursor;
|
|
try {
|
|
Application.RaiseIdle(EventArgs.Empty);
|
|
} finally {
|
|
Cursor.Current = oldCursor;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IServiceProvider
|
|
ServiceContainer services = new ServiceContainer();
|
|
|
|
public object GetService(Type serviceType)
|
|
{
|
|
object obj = services.GetService(serviceType);
|
|
if (obj == null)
|
|
{
|
|
if (serviceType.IsInstanceOfType(this))
|
|
return this;
|
|
}
|
|
return obj;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|