Как реализовать с помощью WinForms в C # что-то вроде изображения с областями карты на домашней странице (при наложении областей покрытия с полупрозрачным прямоугольником)? - PullRequest
2 голосов
/ 23 октября 2011

У меня есть панель (здесь она называется родителем), где я рисую вычисленную картинку. Некоторые прямоугольные области на этом изображении будут выделяться пылесосом. Это то же поведение, что и на веб-странице с использованием, и, e. г. карта Германии на правой верхней стороне .

При пылесосе соответствующий прямоугольник должен быть покрыт наполовину прозрачным синим цветом. (И в зависимости от клавиш, таких как Alt, Ctrl и / или Shift в других цветах, и кликабельны).

Первым решением был отдельный экземпляр прозрачной Panel - унаследованный от класса Panel. В hoovering случае родителя я переместил и изменил размеры единственного экземпляра в нужное место, изменяя цвет. Это было несколько проблем: * перемещение и изменение размера (SetBounds ()) запускают событие MouseLeave родительского объекта и событие MouseEnter отдельной панели. События должны были быть соответствующим образом адаптированы, чтобы заставить его работать правильно, я сделал это, но это было очень медленно, из-за нахождения правильной области карты из списка.

Вторым решением было динамическое создание экземпляра прозрачной панели для каждой области карты. Каждая прозрачная панель должна была установить свою. г. Color.FromArgb (50, Color.Blue) при входе, и удалить его при выходе из панели. Но это кажется еще медленнее, чем раньше. Если мышь спешит по нескольким картам, они все нарисованы, как у них, и снова медленно становятся прозрачными.

Кто-нибудь знает хорошее решение для этих требований:

  • при изменении размера изображения на родительской панели, карте и т. Д. Также необходимо изменить
  • частично прозрачная выделенная область прямоугольника с копчеными краями.
  • обнаружение Ctrl / Shift / Alt как событий для области и изменение цвета.
  • обнаруживать события клика там

Есть ли другие средства управления, которые я бы лучше использовал для этой цели?

Спасибо за идеи, основанные на практике.

PS: Карта мира со спутниковыми снимками лучше показывает, что я хочу сделать: При пылесосе фон все еще виден более или менее. Но в моем случае родительское изображение, его размер и карты рассчитываются во время выполнения (после завершения настроек пользователем).

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Решение

Описание

Я нашел решение, которое достаточно быстро реагирует на пылесосящие участки мышью.
Основные изображения отрисовываются в экземпляре PictureBox, более подробно назначено его свойство Image.
Свойство SizeMode имеет значение Zoom, которое автоматически центрирует и изменяет размер изображения с сохранением соотношения сторон назначенного изображения.
Я использую динамически создаваемый экземпляр Picturebox для каждой области карты (дочерних элементов), который невидим, если на него не наведена мышь.
При наведении курсора на область карты должен появиться дочерний элемент - это делается в событии перемещения мыши родительского PictureBox, где я перебираю дочерние элементы, определяя, находится ли позиция мыши в границах дочерних элементов. Найденный ребенок установлен видимым. Поэтому мышь входит в этот дочерний элемент управления.
В случае отпускания дочернего элемента управления я снова установил его невидимым. Я испытал потерю событий отпускания мыши для дочерних элементов управления, если мышь перемещалась слишком быстро по всем областям карты. Я предполагаю, что если указатель мыши уже покинул область до того, как он стал видимым, событие никогда не вызывается.
Решение состоит в том, что все (другие) дочерние элементы управления становятся невидимыми, если в обработчике событий перемещения мыши родительского элемента управления не обнаруживается (а) дочерний элемент управления.

Шаги для реализации

Что нужно сделать, чтобы реализовать моё решение:

  • Используйте созданный родительский экземпляр PictureBox.
    • Назначить (динамически) нарисованное изображение свойству Image
    • Установите SizeMode на Zoom
    • список Picturebox экземпляров в виде поля формы

При присвоении вновь рассчитанного изображения родительскому элементу Picturebox экземпляр:

  • удалить все дочерние элементы управления, его обработчик событий, его запись из списка, если они уже существуют.
  • динамически создать экземпляр PictureBox для каждой области карты и добавить его в список.
    • добавить его в родительский экземпляр PictureBox в качестве дочернего элемента управления.
    • устанавливает свои свойства Tag указывает на объект данных, содержащий границы исходной карты и объект, представленный прямоугольной областью карты.
    • устанавливает границы для области карты, масштабированной и центрированной в соответствии с границами родительского Picturebox экземпляра, чтобы он соответствовал автоматически увеличенному изображению.
    • зарегистрировать событие щелчка мыши
    • зарегистрировать событие отпуска мыши
    • установить цвет фона на e. г. полупрозрачный зеленый
    • установить Visible в ложь

В родительском экземпляре Picturebox курсор мыши над обработчиком событий выполняет:

  • поиск дочернего Picturebox экземпляра, где указатель мыши указывает на
  • если найдено, найденный ребенок становится видимым
  • установить всех (других) детей Picturebox невидимых

В родительском Picturebox экземпляре обработчик события изменения размера:

  • масштабировать / перемещать все экземпляры области карты Picturebox в соответствии с границами родительского изображения и границами родительского Picturebox экземпляра.

Событие отпускания мыши в каждой области карты Picturebox Экземпляр ставит себя невидимым (потери упомянутых ранее событий). Событие щелчка мышью каждого экземпляра области карты Picturebox делает все, что нужно, щелкнув область карты. Здесь играет синусоидальный тон правильной хроматической высоты.

Фотографии

На рисунках ниже показан прототип с областями карты (еще не выровнены правильно, с некоторым смещением):

Первое изображение предназначено для иллюстрации родительского изображения и всех областей карты. Основное изображение (масштаб) и все области карты (динамически создаваемые дочерние Picturebox экземпляры) отображаются на первом изображении (путем отключения невидимого действия для областей карты).

first picture

Второе изображение продуктивное , где мышь наводит курсор на тон G4.
На втором изображении размер был изменен - ​​поэтому родительское изображение автоматически центрируется и изменяется.Области карты были просто изменены в их свойстве Bound в обработчике события изменения размера родительского элемента PictureBox. И невидимое действие было включено для областей карты.

second picture

0 голосов
/ 25 октября 2011

Я проверил ImageMap : это пользовательский элемент управления, содержащий статическое изображение, которое было нарисовано до времени компиляции.Во время выполнения добавляются интерактивные области - прямоугольник, многоугольник, эллипс.Он использует PictureBox, который создается как дочерний элемент ImageMap (который наследуется от UserControl).Он регистрирует события Click, Move и Leave для своих обработчиков событий.В этих обработчиках событий он проверяет текущую позицию по списку путей в экземпляре GraphicsPath и возвращает индекс (int).Карта изображений отслеживает последний выбранный индекс (-1 = объект не выбран), соответственно устанавливает курсор (вручную или по умолчанию), устанавливает или удаляет всплывающую подсказку.Но у него нет события пылесоса, оно не меняет область при пылесосе, как будто мне это тоже нужно.

Поэтому мне может понадобиться ImageMap для правильного определения области, но моя картинкаобращается во время выполнения!И все же я должен включать и выключать прямоугольники с его полупрозрачным слоем.У меня появилась идея использовать свойство Visible для включения и выключения элементов управления для областей.Чтобы было проще рисовать, я установлю фон той части родительского изображения, которая будет полупрозрачной, - это обходной путь, который возможен, поскольку карты относительно привязаны к родительскому изображению.Если у меня будет время, я протестирую эту идею решения - это частный проект, поэтому я не могу работать полный рабочий день: -).

...