Лучший способ написать пользовательский контроль датчика в WPF? - PullRequest
1 голос
/ 23 апреля 2009

Мне нужно написать датчик контроля в WPF для проекта на работе. Под управлением датчиком я подразумеваю нечто похожее на традиционный автомобильный спидометр: круглое лицо с цифрами и метками по окружности и стрелка, указывающая на текущее значение. Хотя я мог бы заставить своего работодателя купить сторонний элемент управления или даже найти где-нибудь бесплатный, я все же хотел бы написать его сам, ради любопытства, больше всего на свете.

Моей первой мыслью было «оформить» существующий элемент управления, используя шаблон, например, что-то вроде ProgressBar, так как он имеет свойства Minimum, Maximum и Value. Однако я не думаю, что это даст мне ту гибкость, которая мне нужна.

Мне бы хотелось анимировать стрелку, которая указывает на текущее значение, чтобы при изменении значения датчика стрелка переходила от старого значения к новому значению. Я подумал, что самый простой способ сделать это - создать некую форму или геометрию, представляющую иглу, а затем применить RotateTransform соответствующего числа градусов, чтобы стрелка указывала на правильное значение. Свойству To анимации будет присвоено свойство «значения градусов» посредством привязки.

Мне кажется, что есть три основных подхода:

Используйте один пользовательский FrameworkElement для представления всего датчика
Я мог бы наследовать от FrameworkElement, переопределить его метод OnRender, а затем использовать DrawingContext, чтобы нарисовать как грань датчика, так и стрелку. Это означало бы, что я больше не мог анимировать иглу напрямую, используя RotateTransform, а вместо этого должен был бы перерисовывать весь датчик каждый раз, когда значение изменяется. Это кажется мне неэффективным, так как грань датчика представляет основную часть кода чертежа, но изменяется очень редко. Однако этот подход является наиболее легким с точки зрения количества используемых элементов.

Используйте два пользовательских элемента FrameworkElement, один для лица и один для иглы
Я сейчас склоняюсь к этому подходу. Один элемент представляет лицо, а другой - иглу. Это позволило бы мне нацелить игольчатый элемент с помощью RotateTransform. В этом случае управление датчиком будет состоять из трех элементов: лица, иглы и контейнера Panel, в котором будут храниться оба элемента (т. Е. Canvas, Grid и т. Д.). Таким образом, три элемента вместо одного, следовательно, не такие легкие, как при первом подходе.

Используйте DrawingVisuals для рисования лица и иглы
Я также читал о классе DrawingVisual, но меня немного смущает вопрос, почему кто-либо будет использовать это, а не наследует от FrameworkElement и переопределяет OnRender, учитывая, что DrawingVisual должен быть размещен в любом случае в пользовательском FrameworkElement. Казалось бы, этот подход не дает никаких преимуществ по сравнению со вторым подходом и потребует больше кода, но, возможно, я что-то упускаю.

Любые мысли или советы относительно того, какой подход люди считают наилучшим и почему следует приветствовать!

Ответы [ 2 ]

1 голос
/ 24 апреля 2009

Вы можете просто оформить ползунок и ввести в него значения. Вы должны быть в состоянии сделать слайдер похожим на любой необходимый вам датчик.

1 голос
/ 23 апреля 2009

Лично я бы порекомендовал сделать CustomControl, используя второй подход. Если вы не собираетесь показывать более 1000 индикаторов одновременно, вы не заметите дополнительный элемент в вашем визуальном дереве, и я думаю, вы обнаружите, что его гораздо проще создавать и обслуживать. *

...