Я пишу плагин для торгового программного обеспечения (C#, winforms, .NET 3.5), и я хотел бы нарисовать перекрестие курсора над панелью (допустим, ChartPanel
), который содержит данные, которые могут быть дороже краски. Что я сделал до сих пор:Существующие графики в растровые изображения
- Я добавил
CursorControl
к панелям- это
CursorControl
расположена над главной панелью рисования так, чтобы она покрывала это вся область - это
Enabled = false
так, что все входные события передаются родителюChartPanel
- это
Paint
метод реализован таким образом, что он рисует линии сверху вниз и слева направо в текущей позиции мыши
- это
- Когда MouseMove событие вызывается, у меня есть две возможности:
- ) призыв
ChartPanel.Invalidate()
, но, как я сказал, основные данные могут быть дорогими, чтобы рисовать и это приведет к тому, чтобы все перерисовывать каждый раз я двигаю мышь , что является неправильным (но это единственный способ, которым я могу сделать эту работу сейчас) - B) Вызвать
CursorControl.Invalidate()
и до того, как курсор будет нарисован, я бы сделал снимок данных, нарисованных в настоящее время, и сохранил их как фон для курсора, который будет просто восстановлен каждый раз, когда курсор нужно перекрасить ... проблема с этим ... Я не знаю, как это сделать.
- ) призыв
2.б. Это будет означать, чтобы:
- Turn существующий
Graphics
объект вBitmap
(она (Graphics) дается мне через метод Paint, и я должен рисовать на ней, так что я просто не могу создать новый объект Graphics. .. может быть, я получаю это неправильно, но это, как я понимаю) - до перекрестия расписано, восстановление графика содержимого из Bitmap и перекрашивать перекрестие
Я не могу контролировать процесс картины дорогих данных. Я могу просто получить доступ к моим CursorControl
и его методам, которые вызывается через API.
Итак, есть ли способ сохранить существующее графическое содержимое в Bitmap и восстановить его позже? Или есть лучший способ решить эту проблему?
ПОСТАНОВИЛ: После многих часов проб и ошибок я придумал рабочее решение. Есть много проблем с программным обеспечением я использую, которые не могут быть обсуждены в целом, но основные принципы ясны:
- существующих графики с уже нарисованной вещью не могут быть преобразованы непосредственно Bitmap, вместо этого я должен был использовать
panel.DrawToBitmap
способ впервые упомянутый в @ Gusman ответ.Я знал об этом, я хотел этого избежать, но в конце концов я должен был согласиться, потому что это единственный способ: - Также я хотел избежать двойного рисования каждого кадра, поэтому первая краска для перекрестия всегда рисуется непосредственно на
ChartPanel
. После перемещения мыши без изменения изображения диаграммы я делаю снимок черезDrawToBitmap
и продолжаю, как описано в выбранном ответе. - управления должно быть непрозрачным (не включен прозрачным фон), чтобы освежать это не вызывает краски на нем родительское управление (что могло бы привести весь график перекрашивать)
Я до сих пор испытываю случайные мерцания каждым несколько секунд или около того, но я думаю, что могу как-то это понять. Хотя я выбрал ответ Гусмана, я хотел бы поблагодарить всех участников, поскольку я использовал много других трюков, упомянутых в других ответах, таких как Panel.BackgroundImage, использование метода Plot() вместо Paint() для блокировки изображения и т. Д.
В отличие от сайтов форума, мы не используем «Спасибо» или «Любая помощь приветствуется», или подписи на [так ]. См. «[Должны ли« Привет »,« спасибо », теги и приветствия удалены из сообщений?] (Http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be -removed-from-posts). –
Что касается наличия второй панели, расположенной поверх другой, которая имеет прозрачный фон и используется исключительно для рисования курсора (с линиями). Кроме того, убедитесь, что все двойное буферизовать и оптимизировать сложную покраску, где это возможно (например, обеспечить, чтобы все вычисления выполнялись внутри функции «загрузка», а не в событии рисования) – musefan
«Я не могу контролировать процесс рисования дорогих данных» - может вы, по крайней мере, контролируете и/или реагируете на любые изменения данных, которые могли бы потребовать обновления диаграммы? Если это так, тогда вы сможете (в зависимости от того, как реализован элемент управления диаграммой) буферизировать рендеринг диаграммы путем подклассификации , переопределяя 'OnPaint()' и перехватывая рендеринг. Если нет, то b ig challenge здесь обнаруживает, когда визуализированная диаграмма изменилась, так что вы знаете, когда обновлять внеэкранную копию элемента управления (что делает внеэкранную копию сама по себе не слишком сложной). –