У меня есть приложение MDI, которое позволяет мне открывать различные типы дочерних окон. Я могу открыть несколько (но разных) экземпляров дочернего окна одного и того же типа. (Пример: я могу открыть 3 экземпляра дочернего окна типа A и 2 экземпляра дочернего окна типа B. Все 5 окон являются отдельными объектами и не обмениваются данными до тех пор, пока пользователь явно не перетащит одни и те же данные в несколько окон.) Каждое дочернее окно имеет ToolStripContainer с одним или несколькими ToolStrips. Как предотвратить:
Я пытаюсь запретить пользователю перетаскивать ToolStrip из экземпляра 1 типа A в экземпляр 2 типа A, выбирая что-то в экземпляре 2, а затем нажимая кнопку на панели инструментов только для того, чтобы что-то странное произошло с другим окном . Точно так же не имеет смысла перетаскивать ToolStrip из окна типа A в окно типа B - действия не применяются к этому типу, но для пользователя кажется, что все в порядке, потому что я позволяю им делать сопротивление.
Это так же просто, как добавить мой собственный обработчик для события ControlAdded, или есть лучший способ сделать это? Я использую WinForms в .NET 3.0.
изменить: шаги по воспроизведению
См. Шаги репо. Существует только один экземпляр формы с двумя отдельными пользовательскими элементами управления, а не два экземпляра формы.





Пробовали ли вы использовать события DragEnter и DragLeave в ToolStripContainer, чтобы идентифицировать ToolStrip, перетаскиваемый по контейнеру, и принимать или отклонять его?
Это работает, только если у вас есть доступ ко всем ToolStripContainers. См. Пример A / B выше.
Я пытался воспроизвести вашу проблему, но ToolStrips не позволяют перетаскивать их из одного экземпляра в другой (даже одного типа). Итак, то, что вы запрашиваете, должно быть поведением по умолчанию ...
Я могу воспроизвести это (следуя вашим шагам)
Это похоже на взлом, но он работает (вроде) (извините, 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, и заставить его выполнять всю работу за вас, что означает хорошее инкапсулированное решение.
Это работает только в том случае, если у вас есть доступ ко всему коду для полосок инструментов. См. Шаг 8 моих шагов по воспроизведению в заявке. (На самом деле я не уверен, что это вообще работает: похоже, вы прикрепляете обработчик событий к событию ToolStrip.EndDrag. Встроенный обработчик все равно будет работать и выполнять операцию удаления. Достаточно легко исправить, если у вас есть все исходный код панели инструментов, а я нет.)
Я попытался воспроизвести возникшую у вас проблему, но не могу заставить ее работать. Как только я создаю два экземпляра одной и той же формы, я не могу перетащить панель инструментов с одного на другой.