设计时拖放

问题描述 投票:5回答:2

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

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

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

题 :

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

我发现了什么:

  • 有一个内置的功能可以自动地从IToolboxService拖放到System.ComponentModel.Design.DesignSurface,但如果你从零开始实现IDesignerHost,它显然无效。
  • 当您使用Control.DoDragDrop(ToolboxItem)方法时,要启动拖放操作: 调用IToolboxService.SerializeToolboxItem(ToolboxItem)来序列化该项目 IToolboxService.IsToolboxItem(object)IToolboxService.IsSupported(object)被要求评估是否 可以允许序列化的ToolboxItem在设计图面上进行droped 当您放下控件时:设计图面调用IToolboxService.DeserializeToolboxItem(object serializedObject)以反序列化控件。
  • 调用IToolboxService.SetCursor()来了解您是否定义了自定义光标,或者让标准窗口光标。

问题:

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

  • 我拖动,一切都很好,但当悬停在设计表面时,我的光标在标准光标和“DragDropEffects.Copy”风格之间略微闪烁。
  • 当我放下时,没有任何反应,当我的光标离开设计表面时(在我放下之后),然后创建新的Control并添加到我丢弃它的地方。

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

谢谢=)

c# drag-and-drop design-time
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 the Designer中找到一些东西,它解决了Visual Studio版本2003和2005之间拖放的变化行为;很可能这可能是相关的,并且其中一个可接受的答案实际上特别引用了上面的Microsoft Connect问题,而且它也为可能的解决方案提供了更多提示。


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);
© www.soinside.com 2019 - 2024. All rights reserved.