у вас, кажется, есть нужные инструменты, WPF Unleashed отлично, но я думаю, у вас уже есть этот.
сделать отдельные пользовательские элементы управления в одном из следующих случаев:
- вы используете один и тот же xaml повсюду (СУХОЙ)
- ваш xaml-файл становится слишком большим (выведите некоторые компоненты)
- вам нужно наследовать от какого-то класса
это зависит от того, сколько кода вы хотите.
как вы предложили в своем комментарии, вы можете использовать ItemsControl в качестве контейнера для любого выбора между несколькими элементами. так что это также может быть сделано на уровне кривых, а не только на уровне точек на кривой. В зависимости от того, как вы хотите обрабатывать рисование реальных линий и кривых, вы можете даже использовать ItemsControl для них. (примечание: у вас не будет виртуализации из коробки, хотя ваши предметы не будут иметь постоянной высоты)
- Путь в порядке с сотнями точек кривой. Если у вас есть 10.000, я бы сказал, что у вас могут быть проблемы.
- не могу представить, как здесь использовать преобразование, возможно, внутри Adorner.
- ваша структура выглядит хорошо. Вы сможете реализовать все это. Я предложу, однако, как я бы это сделал:
в первую очередь используйте MVVM.
EditPointControl
- Холст
- Thumb (Template = Ellipse) (Name = CenterHandle) (с некоторыми визуальными состояниями для выбора и скрытия касательных)
- Большой палец (Шаблон = Эллипс) (Имя = LeftHandle)
- Большой палец (Шаблон = Эллипс) (Имя = RightHandle)
- Линия (привязка X / Y к центральной точке и LeftHandlePoint)
- Линия (привязка X / Y к центральной точке и RightHandlePoint)
Я указывал установить ItemTemplate для ListBox. Однако вы можете стилизовать список по своему усмотрению (я думаю, что стандартный стиль включает в себя границу, вы можете удалить ее или установить borderize = 0) и установить вместо ItemTemplate ItemContainerStyle и привязать к IsSelected, чтобы вы могли иметь контроль над IsSelected из вашей ViewModel (посмотрите, что я имею в виду здесь ).
Итак, модель представления выглядит так:
- CurveEditorViewModel
- ObservableCollection<CurveViewModel> Curves
- CurveViewModel
- string Label
- (Point LabelPlacement)
- bool IsSelected
- ObservableCollection<CurvePointViewModel> CurvePoints
- ObservableCollection<CurvePartViewModel> CurveParts
- CurvePointViewModel
- Point Position
- bool IsSelected
- Point LeftHandle
- Point RightHandle
- CurvePartViewModel
- CurvePointViewModel StartPoint
- CurvePointViewModel EndPoint
- Path CurvePath
здесь вы можете подписаться на PropertyChanged объекта CurvePointViewModel и пересчитать путь, который вы открываете.
Я бы, вероятно, улучшил бы это, когда я иду, но это было бы моим первым предположением.
Есть некоторые детали, которые вы можете не упустить. Например: стиль для больших пальцев может быть видимым кругом посередине и невидимым большим вокруг с фоном = прозрачный. таким образом, вы можете сделать видимый круг маленьким, но пользователь должен использовать палец в области вокруг маленького круга.
EDIT
Вот пример для большого пальца:
<Thumb Width="8" Height="8" Cursor="Hand" Margin="-4">
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Grid>
<Ellipse Fill="Transparent" Margin="-6"/>
<Ellipse Stroke="Red" StrokeThickness="2"/>
</Grid>
</ControlTemplate>
</Thumb.Template>
</Thumb>
, так как вы хотите расположить это в определенной точке на холсте, установив Margin равным минус половине ширины и высоты, центр круга будет помещен в эту точку. Кроме того, имея этот внутренний эллипс с прозрачной заливкой и полем -6, вы получите радиус в 6 раз больше вокруг внутреннего (меньшего) круга, куда вы можете перетаскивать большой палец.