簡體   English   中英

C#在自定義表單設計器上實現剪切/復制/粘貼

[英]C# Implementing Cut/Copy/Paste on Custom Form Designer

我正在使用的代碼的自定義窗體設計器這篇文章 除了添加“剪切,復制和粘貼”之類的功能外,其他所有功能都工作正常。 示例代碼提供了正常工作的“刪除”控制代碼。 但是,當我嘗試下面的代碼進行剪切/復制/粘貼時,它不起作用。 任何想法?

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);
 }

以下是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();
        }
    }

從我看來

似乎您沒有將MenuCommands添加到MenuCommands列表對象

public bool GlobalInvoke(System.ComponentModel.Design.CommandID commandID)
    {
        foreach(MenuCommand command in menuCommands)
        {
            if (command.CommandID == commandID)
            {
                command.Invoke();
                break;
            }
        }

        return false;
    }

在您的代碼中,您正在檢查MenuCommand列表中是否已經存在MenuCommand。

因此,我認為在初始化命令列表時,請確保在嘗試調用invoke方法之前將其添加到列表中

menuService.AddCommand(StandardCommands.Delete)

您可以檢查https://docs.microsoft.com/zh-cn/dotnet/api/system.componentmodel.design.standardcommands?view=netframework-4.8 ,了解如何將StandardCommand添加到menuCommands

我解決了我的問題。 它只需要添加一些序列化。 如下所示:

_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);
}

請參閱鏈接以獲取更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM