I am working on a custom form designer using the code in the this article . Everything is working fine except when Adding a functionality like Cut, Copy & Paste. The sample code provide a code for Deleting control which is working fine. But when I try the code below to Cut/Copy/paste, it's not working. Any idea?
private ServiceContainer serviceContainer = null;
private MenuCommandService menuService = null;
private void Initialize()
{
IDesignerHost host;
Form form;
IRootDesigner rootDesigner;
Control view;
// Initialise service container and designer host
serviceContainer = new ServiceContainer();
serviceContainer.AddService(typeof(INameCreationService), new NameCreationService());
serviceContainer.AddService(typeof(IUIService), new UIService(this));
host = new DesignerHost(serviceContainer);
// Add toolbox service
serviceContainer.AddService(typeof(IToolboxService), lstToolbox);
lstToolbox.designPanel = pnlViewHost;
PopulateToolbox(lstToolbox);
// Add menu command service
menuService = new MenuCommandService();
serviceContainer.AddService(typeof(IMenuCommandService), menuService);
// Start the designer host off with a Form to design
form = (Form)host.CreateComponent(typeof(Form));
form.TopLevel = false;
form.Text = "Form1";
// Get the root designer for the form and add its design view to this form
rootDesigner = (IRootDesigner)host.GetDesigner(form);
view = (Control)rootDesigner.GetView(ViewTechnology.WindowsForms);
view.Dock = DockStyle.Fill;
pnlViewHost.Controls.Add(view);
// Subscribe to the selectionchanged event and activate the designer
ISelectionService s = (ISelectionService)serviceContainer.GetService(typeof(ISelectionService));
s.SelectionChanged += new EventHandler(OnSelectionChanged);
host.Activate();
}
private void PopulateToolbox(IToolboxService toolbox)
{
toolbox.AddToolboxItem(new ToolboxItem(typeof(Button)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(ListView)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(TreeView)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(TextBox)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(Label)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(TabControl)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(OpenFileDialog)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(CheckBox)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(ComboBox)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(GroupBox)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(ImageList)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(Panel)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(ProgressBar)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(ToolBar)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(ToolTip)));
toolbox.AddToolboxItem(new ToolboxItem(typeof(StatusBar)));
}
private void OnSelectionChanged(object sender, System.EventArgs e)
{
ISelectionService s = (ISelectionService)serviceContainer.GetService(typeof(ISelectionService));
object[] selection;
if (s.SelectionCount == 0)
propertyGrid.SelectedObject = null;
else
{
selection = new object[s.SelectionCount];
s.GetSelectedComponents().CopyTo(selection, 0);
propertyGrid.SelectedObjects = selection;
}
if (s.PrimarySelection == null)
lblSelectedComponent.Text = "";
else
{
IComponent component = (IComponent)s.PrimarySelection;
lblSelectedComponent.Text = component.Site.Name + " (" + component.GetType().Name + ")";
}
}
private void mnuDelete_Click(object sender, System.EventArgs e)
{
menuService.GlobalInvoke(StandardCommands.Delete);
}
private void menuItem2_Click(object sender, EventArgs e)
{
menuService.GlobalInvoke(StandardCommands.Cut);
}
private void menuItem4_Click(object sender, EventArgs e)
{
menuService.GlobalInvoke(StandardCommands.Paste);
}
private void menuItem3_Click(object sender, EventArgs e)
{
menuService.GlobalInvoke(StandardCommands.Copy);
}
Below is the code for MenuCommandService
internal class MenuCommandService : IMenuCommandService
{
ArrayList menuCommands = null;
public MenuCommandService()
{
menuCommands = new ArrayList();
}
public void AddCommand(System.ComponentModel.Design.MenuCommand command)
{
menuCommands.Add(command);
}
public void AddVerb(System.ComponentModel.Design.DesignerVerb verb)
{
// No implementation
}
public System.ComponentModel.Design.MenuCommand FindCommand(System.ComponentModel.Design.CommandID commandID)
{
return null;
}
public bool GlobalInvoke(System.ComponentModel.Design.CommandID commandID)
{
foreach(MenuCommand command in menuCommands)
{
if (command.CommandID == commandID)
{
command.Invoke();
break;
}
}
return false;
}
public void RemoveCommand(System.ComponentModel.Design.MenuCommand command)
{
menuCommands.Remove(command);
}
public void RemoveVerb(System.ComponentModel.Design.DesignerVerb verb)
{
// No implementation
}
public void ShowContextMenu(System.ComponentModel.Design.CommandID menuID, int x, int y)
{
// No implementation
}
public System.ComponentModel.Design.DesignerVerbCollection Verbs
{
get
{
return new DesignerVerbCollection();
}
}
From what I see,
It seems you are not adding the MenuCommands to the MenuCommands list object
public bool GlobalInvoke(System.ComponentModel.Design.CommandID commandID)
{
foreach(MenuCommand command in menuCommands)
{
if (command.CommandID == commandID)
{
command.Invoke();
break;
}
}
return false;
}
In your code, you are checking if the MenuCommand already exists in the list of MenuCommands.
So I think when you initialise the list of commands, make sure to add that to the list before trying to call the invoke method
menuService.AddCommand(StandardCommands.Delete)
You can check https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.design.standardcommands?view=netframework-4.8 on how to add a StandardCommand to the menuCommands
I resolved my problem. It just need to add some serialization. like below:
_codeDomComponentSerializationService = new CodeDomComponentSerializationService(serviceContainer);
if (_codeDomComponentSerializationService != null)
{
serviceContainer.RemoveService(typeof(ComponentSerializationService), false);
serviceContainer.AddService(typeof(ComponentSerializationService), _codeDomComponentSerializationService);
}
_designerSerializationService = new
DesignerSerializationServiceImpl(serviceContainer);
if (_designerSerializationService != null)
{
serviceContainer.RemoveService(typeof(IDesignerSerializationService), false);
serviceContainer.AddService(typeof(IDesignerSerializationService), _designerSerializationService);
}
See link for more details.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.