5

我目前正在从事一个项目,我的职责是设计一个设计表面,最终用户可以在运行时添加/删除/移动控件。

我遵循了本教程“Hosting Windows Forms Designers, by Tim Dawson”,并且几乎实现了我需要的所有功能。

给那些不想阅读教程的人的短篇故事:我实现IDesignerHostIContainerISelectionServiceIToolboxService其他一些界面,以创建我的设计界面。我没有使用System.ComponentModel.Design.DesignSurface已经在框架中的,主要是因为我需要一个真正定制的设计表面。

问题 :

Control我想允许用户将新的从拖放IToolboxServiceIDesignerHost/IContainer. 在本教程中,您Control单击工具箱中的一个,单击设计表面以添加控件。

我发现了什么:

  • IToolboxService有一个内置功能可以自动从to 拖放 ,System.ComponentModel.Design.DesignSurface但如果您从无到有实现 IDesignerHost,它显然不起作用。
  • 当您使用该 Control.DoDragDrop(ToolboxItem) 方法时,启动拖放:

    1. IToolboxService.SerializeToolboxItem(ToolboxItem) 被调用来序列化项目
    2. IToolboxService.IsToolboxItem(object) 并被
      IToolboxService.IsSupported(object) 调用以评估是否
      可以允许将序列化的 ToolboxItem 拖放到设计图面上
    3. 当您放置控件时:IToolboxService.DeserializeToolboxItem(object serializedObject)由设计图面调用以反序列化已放置的控件。
  • IToolboxService.SetCursor()调用以了解您是定义自定义光标还是让标准窗口光标。

问题 :

我在“我发现了什么”中实现了上面提到的所有内容,但是拖放是错误的:

  • 我拖动,一切都很好,但是当悬停在设计表面时,我的光标在标准光标和“ DragDropEffects.Copy”样式之间闪烁了一下。
  • 当我放下时,什么也没有发生,当我的光标离开设计表面时(在我放下之后),然后新Control的被创建并添加到我放下它的地方。

有没有人尝试过我正在做的事情,如果有,你是如何做到的?有没有人有任何指针/链接/好的建议?

谢谢你=)

4

2 回答 2

3

有没有人有任何指针/链接/好的建议?

您的问题似乎已通过 Microsoft Connect 问题Mouse Events Consumed / Not Raised in 2.0 Designers得到解决。虽然这个问题很容易掌握,但显然从 .NET Framework 1.1 (2003) 升级到 2.0 (2006) 意味着拖放行为发生了变化——鉴于您提到的文章源于 2003 年,这很可能是相关的. 具体来说,您应该向前滚动到第2部分,引文:

您现在会注意到在表单上拖动时会不断闪烁。这部分是由 2.0 中的新拖放行为引起的。

我自己现在无法更深入地研究这一点,但您也可以从Customize Drag & Drop in Designer 中找到一些东西,它解决了 Visual Studio 版本 2003 和 2005 之间有关拖放的更改行为;很可能这可能是相关的,并且接受的答案之一实际上确实特别提到了上面的 Microsoft Connect 问题,而且它也提供了更多关于可能解决方案的提示。

于 2009-09-22T03:21:47.770 回答
0

一天前我要解决这个问题。这是我为像您这样的项目找到的解决方案。

  1. 我拖动,一切都很好,但是当悬停在设计表面时,我的光标在标准光标和“DragDropEffects.Copy”样式之间闪烁了一下。

这是我的工具箱服务。

class EasyAccordionToolboxService : AccordionControl, IToolboxService
{
    EasyAccordionControlElement _SelectedElement;
    public Control DesignPanel { get; set; }

    public EasyAccordionToolboxService()
    {
        AddAccordions();
        AllowItemSelection = true;
        base.ElementClick += EasyAccordionToolboxService_ElementClick;
    }

    private void EasyAccordionToolboxService_ElementClick(object sender, ElementClickEventArgs e)
    {
        if (e.Element.Level == 1) this._SelectedElement = e.Element as EasyAccordionControlElement;
    }

    public ToolboxItem GetSelectedToolboxItem()
    {
        if(_SelectedElement != null)
        {
            var selectedToolboxItem = this._SelectedElement.ToolBoxItem;
            this._SelectedElement = null;
            return selectedToolboxItem;
        }
        else
        {
            return null;
        }
    }

        public bool SetCursor()
    {
        if(this._SelectedElement == null)
        {
            this.DesignPanel.Cursor = Cursors.Default;
        }
        else
        {
            this.DesignPanel.Cursor = Cursors.Hand;
        }

        return true;
    }

有“DesignPanel”属性和“SetCursor”方法。DesignPanel 属性是引用根设计器视图的控件。

  1. 当我放下时,什么都没有发生,当我的光标离开设计表面时(在我放下之后),新的 Control 被创建并添加到我放下它的地方。

EasyAccordionToolBoxService 中有GetSelectedToolboxItem 方法,它是由IToolboxService 实现的。GetSelectedToolboxItem 是您的答案。

最后,

        designer = new EasyDesignSurface(propertyGrid);

        var rootForm = (Form)designer.CreateComponent(typeof(Form));
        rootForm.Name = "rootForm";
        rootForm.Text = "BELGE";
        rootForm.TopLevel = false;
        rootForm.Size = new Size(600, 600);
        designer.ComponentContainer.Add(rootForm);

        var view = (Control)designer.View;
        view.Dock = DockStyle.Fill;
        designPanel.Controls.Add(view);

        easyAccordionToolboxService1.DesignPanel = view;
        designer.AddService(typeof(IToolboxService), easyAccordionToolboxService1);
于 2019-03-19T11:31:43.210 回答