Перетаскивание во время разработки - PullRequest
5 голосов
/ 18 сентября 2009

В настоящее время я работаю над проектом, в котором моя часть заключается в разработке рабочей поверхности, в которой конечный пользователь может добавлять / удалять / перемещать элементы управления во время выполнения.

Я следовал этому уроку "Хостинг дизайнеров Windows Forms Тима Доусона" и почти реализовал все необходимые мне функции.

Рассказ для тех, кто не хочет читать учебник: Я реализовал IDesignerHost, IContainer , ISelectionService, IToolboxService и некоторые другие интерфейсы для создания моей поверхности дизайна. Я не использовал System.ComponentModel.Design.DesignSurface уже в фреймворке, в основном потому, что мне нужна действительно нестандартная поверхность дизайна.

Вопрос:

Я хочу разрешить пользователю перетаскивать новые Control из IToolboxService в IDesignerHost/IContainer. В этом руководстве вы нажимаете Control на панели инструментов, щелкаете мышью по области конструктора, чтобы добавить элемент управления.

Что я нашел:

  • Существует встроенная функция, которая автоматически перетаскивает из IToolboxService до 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() вызывается, чтобы узнать, определяете ли вы пользовательский курсор или разрешаете стандартный курсор Windows.

Проблема:

Я реализовал все, что упомянуто выше, в «Что я нашел», но перетаскивание глючит:

  • тащу, все нормально, но когда парить поверхность дизайна, мой курсор мигает немного между стандартный курсор и Стиль "DragDropEffects.Copy".
  • Когда я перетаскиваю, ничего не происходит, и когда мой курсор покидает поверхность дизайна (после того, как я уронил), тогда создается новый Control, который добавляется туда, где я его уронил.

Кто-нибудь когда-нибудь пытался делать то, что я делаю, и если да, то как тебе это удалось? Есть ли у кого-нибудь указатель / ссылка / хорошие советы?

Спасибо =)

Ответы [ 2 ]

3 голосов
/ 22 сентября 2009

Есть ли у кого-нибудь указатель / ссылка / хорошие советы?

Похоже, что ваша проблема решена с помощью проблемы Microsoft Connect События мыши, использованные / не возникшие в версии 2.0Конструкторы .Хотя эту проблему легко понять, но, очевидно, обновление .NET Framework 1.1 (2003) до 2.0 (2006) подразумевало изменение поведения перетаскивания - учитывая, что упомянутая вами статья относится к 2003 году, это вполне может быть связано,В частности, вы должны прокрутить вперед до раздела Issue 2 , цитата:

Теперь вы будете замечать постоянное мерцание при перетаскивании по форме.Это частично вызвано новым поведением перетаскивания в 2.0.

Я не могу сейчас углубиться в это глубже, но вы также можете найти что-то из Customize Drag& Drop в конструкторе , который учитывает измененное поведение в отношении перетаскивания между версиями Visual Studio 2003 и 2005;вполне вероятно, что это может быть связано, и один из принятых ответов на самом деле конкретно ссылается на проблему Microsoft Connect выше, плюс он также предлагает больше подсказок относительно возможных решений.

0 голосов
/ 19 марта 2019

Я работал над этим вопросом один день назад. Это мое решение, которое нашел для моего проекта, как ваш.

  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. Когда я перетаскиваю, ничего не происходит, и когда мой курсор покидает поверхность дизайна (после того, как я упал), тогда создается новый элемент управления и добавляется туда, где я его отбрасывал.

В 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);
...