设计时拖放

时间:2009-09-18 09:27:36

标签: c# drag-and-drop design-time

我目前正在开展一个项目,我的目标是设计一个Design Surface,最终用户可以在运行时添加/删除/移动控件。

我遵循了本教程"Hosting Windows Forms Designers, by Tim Dawson",几乎已经实现了我需要的所有功能。

那些不想阅读教程的人的简短故事: 我实施了IDesignerHostIContainerISelectionServiceIToolboxService和其他一些界面,用于创建我的设计图面。我没有在框架中使用System.ComponentModel.Design.DesignSurface,主要是因为我需要一个非常自定义的设计表面。

问题:

我想让用户拖动&将新ControlIToolboxService放到IDesignerHost/IContainer。在本教程中,您将在工具箱中的Control上单击,单击设计图面以添加控件。

我发现了什么:

  • 有一个内置功能 自动化拖动和放大从...下降 IToolboxServiceSystem.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并添加到放弃它的位置。

有没有人试图做我正在做的事情,如果有的话,你是如何管理它的? 有没有人有任何指针/链接/好建议?

谢谢=)

2 个答案:

答案 0 :(得分:3)

  

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

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

  

你现在会注意到不变   拖动时闪烁   形成。这部分是由于   2.0中的新拖放行为。

我现在无法深入研究这个问题,但你也可以从Customize Drag & Drop in the Designer找到一些东西,它解决了关于阻力和阻力的变化行为。在Visual Studio版本2003和2005之间删除;很可能这可能是相关的,其中一个已接受的答案实际上特别引用了上面的Microsoft Connect问题,而且它也为可能的解决方案提供了更多提示。

答案 1 :(得分: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. 当我放下时,什么也没有发生,当我的光标离开设计图面(放下后)时,就会创建新的控件并将其添加到我放下它的位置。

从IToolboxService实现的EasyAccordionToolBoxService中有GetSelectedToolboxItem方法。 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);