Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Отрисовка своих контролов


Автор: Wilko 1.3.2011, 17:22
Здравствуйте. Извините за, может быть, туповатый вопрос. Но в графике не силен.
Необходимо создать класс описывающий линию с дополнительным функционалом(аналог Ручки в фотошопе, только без кривых). Т.е. с добавлением, удалением, перемещением узловых точек линии. Вопрос, как организовать отрисовку всего этого дела? При этом нужно, чтобы не терялась связность линии. Т.е. при удалении средней точки линия просто меняла направление на следующую точку(не знаю как яснее выразиться). И соответственно возможность привязаться на эвенты мыши. Никак сдвинуться с мертвой точки не могу. Мб у кого-нибудь есть ссылки на статьи, или свой опыт в этом деле  smile  Основная проблема в том, что когда переопределяю onPaint у  своих классов(Line и Dot), то ничего не происходит, как форма была пустая, так и остается. Это можно как нибудь реализовать без хардкодинга в методе onPaint формы? Не хочется все отображение писать в самой форме.


Автор: diadiavova 1.3.2011, 20:17
Вообще, подобные вещи проще реализуются на WPF, но если "кровь с носа" надо на винформах сделать то познакомься с пакетом  Microsoft.VisualBasic.PowerPacks. Он поставляется со студией и в винфорам-проектах VBNet на панели инструментов имеются элементы из него(линия, овал, прямоугольник). 
У меня эта библиотека находится по адресу
 C:\Program Files\Reference Assemblies\Microsoft\VBPowerPacks\v10.0\Microsoft.VisualBasic.PowerPacks.Vs.dll
Там есть небольшой набор фигур, но можно создать свои, унаследовав их он базового класса Shape. 

Если хочешь свою реализацию, то в принципе она должна быть устроена примерно так же как и там, так что этот пакет изучить в любом случае будет неплохо.

Автор: Wilko 1.3.2011, 22:32
А почему это легче реализовать на WPF? Просто до этого особо не сталкивался с WPF, а на формсах уже много чего написано для это программы. Вот только в графике траблы, не охото все переводить на WPF рельсы)
Задача программы состоит в анализе графической информации. Т.е. как таковой отрисовки там минимальное количество, но даже ее не удалось реализовать "с наскока".

p.s. что посоветуете для быстрого перехода на WPF: петцольд, макдональд? Или просто начать писать на WPF?)

Автор: diadiavova 1.3.2011, 23:14
Цитата(Wilko @  1.3.2011,  22:32 Найти цитируемый пост)
А почему это легче реализовать на WPF?

Потому что там используется векторная графика, а в винформах - растровая. Тебе надо, чтобы линия была объектом, чтобы она реагировала на действия пользователя, видоизменялась и прочее. Это все делается посредством векторной графики. То есть тебе придется либо создать свою упрощенную векторную модель на базе растра, либо воспользоваться готовой навороченной. 
Цитата(Wilko @  1.3.2011,  22:32 Найти цитируемый пост)
Просто до этого особо не сталкивался с WPF, а на формсах уже много чего написано для это программы.

Если все просто, воспользуйся пакетом, о котором я написал, там заложено много чего, и реализовать все совсем не сложно (по крайней мере легче, чем осваивать впф с нуля). 


Цитата(Wilko @  1.3.2011,  22:32 Найти цитируемый пост)
 Т.е. как таковой отрисовки там минимальное количество, но даже ее не удалось реализовать "с наскока".

Решение достаточно просто: тебе надо создать абстрактный класс для всех фигур, в нем реализуй абстрактный метод, сигнатура которого будет такой же, как OnPaint контрола. В этом методе все производные классы будут отрисовывать сами себя в соответствии с заданными параметрами. Далее создаешь контрол, в котором будет выполняться прорисовка, в этом контроле создаешь свойство, которое будет содержать коллекцию фигур. Метод OnPaint этого конторола будет сводиться к тому, что тебе надо будет перебрать всю коллекцию фигур в цикле и вызвать у них перерисовку, передав их методу прорисовки PainEventArgs, полученный из параметров. Ничего изощренного. Это, конечно упрощенно, но смысл такой. В упомянутом мной пакете все реализовано по такой схеме.

Цитата(Wilko @  1.3.2011,  22:32 Найти цитируемый пост)
p.s. что посоветуете для быстрого перехода на WPF: петцольд, макдональд? Или просто начать писать на WPF?)


Макдональд неплох, Петцольда не читал. Лучше спроси в соответствующем разделе, или в литературе.

Автор: Wilko 1.3.2011, 23:33
Пугают слова Visual Basic )) Т.к. я пишу на шарпе. Надо будет поискать библиотеку векторной графики для шарпа. Насчет отрисовки. Как передавать объект Graphics нашим объектам? В данный момент мне нужно отрисовывать только линию с опорными точками, так что создавать общий класс не вижу смысла.
Даже если мы создадим контрол в котором у нас будет коллекция наших объектов, как в этой коллекции привязать к каждому объекту свой обработчик?

Автор: diadiavova 1.3.2011, 23:49
Цитата(Wilko @  1.3.2011,  23:33 Найти цитируемый пост)
Пугают слова Visual Basic )) Т.к. я пишу на шарпе.

Хоть на шарпе, хоть на шмарпе - это обычная .Net сборка, которая будет совершенно одинаково работать независимо от языка. 
Цитата(Wilko @  1.3.2011,  23:33 Найти цитируемый пост)
Как передавать объект Graphics нашим объектам?

Я же объяснил, что метод отрисовки должен иметь такую же сигнатуру, как и онпэйнт. То есть у него есть параметр PaintEventArgs, который в свою очередь содержит свойство Graphics. Учитывая, что отрисовку контрола ты будешь выполнять в методе OnPaint, ты получишь этот объект в виде параметра. Его и передавай всем фигурам.
Цитата(Wilko @  1.3.2011,  23:33 Найти цитируемый пост)
Даже если мы создадим контрол в котором у нас будет коллекция наших объектов

Не даже, а так и надо сделать
Цитата(Wilko @  1.3.2011,  23:33 Найти цитируемый пост)
 как в этой коллекции привязать к каждому объекту свой обработчик? 

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

Автор: Wilko 2.3.2011, 00:00
Просто я не понимаю как при этом на каждую опорную точку на линии нам еще повесить события на перетаскивание, удаление и т.п. smile 
Или  всю эту логику нужно реализовать в абстрактном родительском классе?

Автор: diadiavova 2.3.2011, 00:07
Цитата(Wilko @  2.3.2011,  00:00 Найти цитируемый пост)
Просто я не понимаю как при этом на каждую опорную точку на линии нам еще повесить события на перетаскивание, удаление и т.п.

Это уже отдельный вопрос. Тебе в каждой фигуре надо будет иметь ссылку на контрол, в котором будет происходить прорисовка. В этом контроле тебе придется отлавливать некоторые события во всех фигурах. Фигуры будут иметь информацию о том, где находятся точки и все остальное. и если в конроле к примеру мышка клацнула по тому месту, где точка, то фигура должна инициировать событие клика по точке. Если начать думать о деталях, то все окажется не так элементарно, поэтому я и говорю о том, что готовое решение предпочтительнее.

Автор: Wilko 2.3.2011, 12:25
Вот подкинули интересную статейку, мб кому понадобится
http://habrahabr.ru/blogs/net/105306/

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)