В процессе поиска решения для этого вопроса, появился новый вопрос.
У контролов WinForms для работы с Drag'n'Drop в .NET предусмотрено несколько типовых событий и метод DoDragDrop.
Но есть несколько проблем связанных с ними. Если мы активируем DoDragDrop по событию MouseDown, то до завершения процесса перетаскивания окно нашей программы не получает события мыши, но получает события связанные с процедурой перетаскивания. Пока вроде все логично, но если после активации перетаскивания объекта мышь не перемещается, то процедура завершается не сразу, а с неопределенным таймаутом, и в это время события мыши не передаются нашему окну, что собственно и вызвало проблему описанную в вопросе по ссылке выше.
Для TreeView и ListView оказалось есть решение из коробки - событие ItemDrag, но для других контролов, которые потенциально могли бы стать источником для Drag'n'Drop, такого решения не предусмотрено.
Пока в голову пришло только одно решение:
По событию MouseDown поднимать флаг о возможном начале перетаскивания и запоминать потенциальный объект перетаскивания в приватных полях формы.
По событию MouseMove проверять флаг и состояние клавиш мыши, и если заданные условия выполнены, вызвать метод DoDragDrop в параметры которого передать предварительно сохраненный объект в качестве данных для перетаскивания. После этого сбросить флаг.
Но мне почему-то кажется что это костыль, потому что в зависимости от того, что и откуда мы собираемся перетаскивать, код будет различаться и его придется дублировать для каждой формы, в которой потребуется такой функционал.
Собственно вопрос, правильно ли я понимаю, что процесс перетаскивания выполняется в контексте операционной системы, а не отдельных программ, для обеспечения возможности перетаскивания объектов между программами? Если предположение верное, то существует ли решение обойти перечисленные проблемы более гибко, без строительства велосипедов из костылей? Если мое предположение не верно - то в ответе хотелось бы увидеть как это работает на самом деле.
Вопрос адресован скорее знатока WinAPI, но решение хотелось бы получить в контексте C#. В принципе, мне, подойдет любое решение, которое можно будет адаптировать для .NET, если оно будет лучше уже изложенного.
Ответ
Буду рассуждать логически: У тебя не так уж много контролов, которые могут принимать в себя перетаскиваемый обьект. Уверен, их на форме от силы 1-3.
Так почему бы не посмотреть как реализован ItemDrag в TreeView и ListView (благо, соурсы легко гуглятся по запросу "treeview source code") и не реализовать нужный тебе ItemDrag ивент в нужных контролах путем наследования и последующего расширения возможностей?
Код будет, скорее всего, практически, идентичным.(я имею ввиду код ItemDrag для всех наследников оригинальных класов)
Код твоей программы не будет замусориватся лишними флагами и методами. Все будет все так же читабельно, как если бы эти методы там были из коробки :)
Комментариев нет:
Отправить комментарий