我想实现一个相当复杂的CurveEditor,它必须支持通常的需求,如:
我不想操作实际的WPF曲线,而是一个具有键/值/切线集的现有模型,并从我们的实现中对曲线的精确形状进行采样。
我已经积累了一些实现自定义UserControls和模板的经验。但我要确保,我不会错过任何明显的解决方案。我计划有一个通用的XAML树:
- **RightTangent** - UserControl for the right tangent handle
- **RightTangentThumb** - For modifying the handle
- **CurvePointCenter** - Visualisation of the actual point, select state and interpolation type.
- **CurvePointThumb** - Thumb to select and drag point around
我知道,这是一个相当复杂的问题,我并不是要求实际执行。我对以下问题感兴趣:
发布于 2011-03-14 05:33:03
- you are using the same xaml all over the place (DRY)
- you xaml file gets too big (get some components out)
- you _need_ to inherit from some class
首先使用MVVM。
- Canvas(Background=Transparent) <= I'm not sure if standard is white, but you don't want to overlap other Curves...
- CurveName
- ListBox(Panel=Canvas(Background=Transparent))(ItemsSource=CurveParts)
- ListBox(Panel=Canvas(Background=Transparent))(ItemsSource=CurvePoints)(ItemTemplate=>EditPointControl)
- Canvas
- Thumb(Template = Ellipse) (Name=CenterHandle) (with some Visualstates for Selection and hiding of Tangents)
- Thumb(Template = Ellipse) (Name=LeftHandle)
- Thumb(Template = Ellipse) (Name=RightHandle)
- Line (Binding X/Y to Centerpoint and LeftHandlePoint)
- Line (Binding X/Y to Centerpoint and RightHandlePoint)
我已经声明将ItemTemplate设置为ListBox。不过,您可以随意设置列表框的样式(我认为标准样式包括一个边框,您可能希望删除该边框或设置bordersize=0),并将其设置为ItemTemplate ( ItemContainerStyle ),并绑定到IsSelected,这样您就可以从ViewModel中控制IsSelected (我的意思是查看这里 )。
视图模型如下所示:
- 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
在这里,您可以订阅CurvePointViewModel的PropertyChanged并重新计算您要公开的路径。
我可能会改进我的做法,但这将是我的第一猜测。
有些细节你可能需要留心。拇指的样式可能是中间的一个可见的圆圈,和background=transparent周围的一个看不见的更大的圆圈。这样,你就可以让你的可见圈小,但让用户使用在一个区域周围的小圆圈。
编辑
下面是拇指的一个例子:
<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>
当您希望将其定位在画布上的特定点时,将边距设置为减去宽度和高度的一半,将圆心放置在该点上。此外,有一个透明的填充和边缘为-6的内椭圆,你将得到一个6px更大的半径围绕在中心(较小的)圆圈,你可以拖动拇指。
https://stackoverflow.com/questions/5276701
复制