代码之家  ›  专栏  ›  技术社区  ›  Clement Herreman

设计时拖放

  •  5
  • Clement Herreman  · 技术社区  · 17 年前

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

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

    为那些不想阅读本教程的人编写的短篇故事: 我实施 IDesignerHost , IContainer , ISelectionService , IToolboxService 和其他一些界面,来创建我的设计图面。我没有用这个 System.ComponentModel.Design.DesignSurface

    问题:

    我想允许用户拖动&丢弃新的 Control 从 IToolboxService 到 IDesignerHost/IContainer . 在本教程中,您将在 控制 在工具箱中,单击设计图面以添加控件。

    我发现:

    • 有一个内置功能 自动拖动&从 到 但如果您从无到有地实现IDesignerHost,显然是行不通的。
    • 当你使用 Control.DoDragDrop(ToolboxItem) 方法,以启动拖动&删除:

      1. IToolboxService.SerializeToolboxItem(ToolboxItem) 调用以序列化该项
      2. IToolboxService.IsToolboxItem(object) 和
        IToolboxService.IsSupported(object) 调用以评估
        可以允许序列化ToolboxItem 放置在设计图面上
      3. 当您放下控件时: IToolboxService.DeserializeToolboxItem(object serializedObject)
    • IToolboxService.SetCursor()

    我在“我发现了什么”中实现了上面提到的所有内容,但是drag&这是一辆马车:

    • 我拖,一切都好,但什么时候 在设计图面上悬停,我的 光标在两个方向之间稍微闪烁 标准游标和 " DragDropEffects.Copy “风格。
    • 当我拖放时,什么也不会发生,当我的光标离开设计图面(在我拖放之后),新的 控制 创建并添加到我放置的位置。

    有没有人试过做我正在做的事,如果有,你是怎么做到的?

    谢谢=)

    1 回复  |  直到 10 年前
        1
  •  3
  •   Steffen Opel Norm Johanson    17 年前

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

    Mouse Events Consumed / Not Raised in 2.0 Designers . 虽然这个问题很容易理解,但从.NETFramework 1.1(2003)升级到2.0(2006)显然意味着drag&drop behavior——鉴于您提到的文章源于2003年,这很可能与此相关。具体来说,您应该向前滚动到第节 问题2

    现在您将注意到常数 在屏幕上拖动时闪烁 2.0中的新拖放行为。

    Customize Drag & Drop in the Designer ,它解决了有关拖动的更改行为&在VisualStudio2003版和2005版之间下降;这很可能与此相关,事实上,其中一个公认的答案确实明确提到了上述Microsoft Connect问题,此外,它还提供了更多关于可能解决方案的提示。

        2
  •  0
  •   Tolga AYKURT    7 年前

    一天前我一直在研究这个问题。这是我为像你这样的项目找到的解决方案。

    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属性是根设计器视图中引用的控件。

    EasyAccordingToolboxService中存在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);