Как предотвратить стыковку ToolStrip с другим ToolStripContainer?

У меня есть приложение MDI, которое позволяет мне открывать различные типы дочерних окон. Я могу открыть несколько (но разных) экземпляров дочернего окна одного и того же типа. (Пример: я могу открыть 3 экземпляра дочернего окна типа A и 2 экземпляра дочернего окна типа B. Все 5 окон являются отдельными объектами и не обмениваются данными до тех пор, пока пользователь явно не перетащит одни и те же данные в несколько окон.) Каждое дочернее окно имеет ToolStripContainer с одним или несколькими ToolStrips. Как предотвратить:

  1. пользователь перетаскивает ToolStrip из дочернего окна типа A в ToolStripContainer в дочернем окне типа B?
  2. пользователь перетаскивает ToolStrip из одного экземпляра дочернего окна A в ToolStripContainer в других экземплярах того же типа окна?

Я пытаюсь запретить пользователю перетаскивать ToolStrip из экземпляра 1 типа A в экземпляр 2 типа A, выбирая что-то в экземпляре 2, а затем нажимая кнопку на панели инструментов только для того, чтобы что-то странное произошло с другим окном . Точно так же не имеет смысла перетаскивать ToolStrip из окна типа A в окно типа B - действия не применяются к этому типу, но для пользователя кажется, что все в порядке, потому что я позволяю им делать сопротивление.

Это так же просто, как добавить собственный обработчик для события ControlAdded или есть лучший способ сделать это? Я использую WinForms в .NET 3.0.

редактировать: шаги по воспроизведению

  1. Создайте новый проект приложения Windows.
  2. Добавьте новый пользовательский элемент управления. Предоставьте элементу управления ToolStripContainer, который содержит одну ToolStrip с одной кнопкой.
  3. Повторите шаг 2, получив класс UserControl2.
  4. Скомпилируйте решение, чтобы UserControl1 и UserControl2 отображались в вашем наборе инструментов.
  5. Перетащите UserControl1 и UserControl2 на форму. Установите границы, чтобы знать, где они находятся.
  6. Запустите приложение.
  7. Теперь можно перетащить ToolStrip из контейнера в UserControl1 и поместить его в контейнер в UserControl2 (оставив нулевые ToolStrips в UC1 и две ToolStrips в UC2).
  8. Теперь представьте, что у вас есть доступ только к коду в UserControl1. Как предотвратить перетаскивание пользователем ToolStrip из этого экземпляра ToolStripContainer?

person Mike Post    schedule 18.11.2008    source источник
comment
Я попытался воспроизвести возникшую у вас проблему, но не могу заставить ее работать. Как только я создаю два экземпляра одной и той же формы, я не могу перетащить панель инструментов с одного на другой.   -  person Nathan W    schedule 19.11.2008
comment
См. Шаги репо. Существует только один экземпляр формы с двумя отдельными пользовательскими элементами управления, а не два экземпляра формы.   -  person Mike Post    schedule 29.05.2011


Ответы (2)


Это похоже на взлом, но он работает (вроде) (извините, vb.net не C #):

Public Class UserControl2

    Private Sub tsMainMenu_BeginDrag(ByVal sender As Object, ByVal e As System.EventArgs) Handles tsMainMenu.BeginDrag

        tsMainMenu.Tag = tsMainMenu.Parent

    End Sub

    Private Sub ToolStrip1_EndDrag(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsMainMenu.EndDrag


        If Not tsMainMenu.Parent.Parent.Equals(CType(tsMainMenu.Tag, ToolStripPanel).Parent) Then

            CType(ToolStrip1.Tag, ToolStripPanel).Controls.Add(tsMainMenu)
        End If

    End Sub

End Class

Проще говоря; по завершении перетаскивания элемента управления, если его родительский ToolStripContainer не такой, каким он был в момент начала перетаскивания, переместите панель инструментов обратно на место.

Я уверен, что это можно превратить в элемент управления, чтобы вам не приходилось писать его для каждой панели инструментов.

Изменить: вы можете поместить весь этот код в элемент управления, унаследованный от ToolStripContainer, и заставить его выполнять всю работу за вас, что означает красивое инкапсулированное решение.

person Pondidum    schedule 08.05.2009
comment
Это работает, только если у вас есть доступ ко всему коду для полосок инструментов. См. Шаг 8 моих шагов по воспроизведению в заявке. (На самом деле я не уверен, что это вообще работает: похоже, вы присоединяете обработчик событий к событию ToolStrip.EndDrag. Встроенный обработчик по-прежнему будет работать и выполнять операцию удаления. Достаточно легко исправить, если у вас есть все исходный код панели инструментов, а я нет.) - person Mike Post; 24.10.2009

Пробовали ли вы использовать события DragEnter и DragLeave в ToolStripContainer, чтобы идентифицировать ToolStrip, перетаскиваемый по контейнеру, и принимать или отклонять его?

person Hinek    schedule 18.12.2008
comment
Это работает, только если у вас есть доступ ко всем ToolStripContainers. См. Пример A / B выше. - person Mike Post; 07.01.2009
comment
Я пытался воспроизвести вашу проблему, но ToolStrips не позволяют перетаскивать их из одного экземпляра в другой (даже одного типа). Итак, то, что вы запрашиваете, должно быть поведением по умолчанию ... - person Hinek; 12.01.2009
comment
Я могу воспроизвести это (следуя вашим шагам) - person Pondidum; 08.05.2009