2011-03-11 77 views
6

我想实现一个相当复杂的CurveEditor有支持像通常的要求:战略实施与XAML复杂的曲线编辑器/ WPF

  • 自由伸缩和可移动轴每曲线
  • 不同的插补方式点(线性,三次,样条)
  • 切线(加入和碎)
  • 选择一个或几个点进行编辑(移动,缩放,删除),通过围栏或点击
  • 仅显示一个处理第二选定曲线亮点指出

sample illustration of the CurveEditorComponent

我不想操纵实际WPF曲线,但与键/值/切线套现有模型和样品从我们的实现曲线的精确形状。

我已经收集了一些实现自定义用户控件和模板的经验。但我想确保,我不会错过任何明显的解决方案。我计划让这个一般XAML树:

  • CurveEditor - 窗口保存所有内容
    • MainThumb:允许在拖动和缩放编辑器范围
    • X轴:用户控件撕心裂肺一些在左侧的比例尺
    • YAxis:UserControl在底部显示一些比例
    • 曲线:帆布保持曲线
      • 曲线:用户控件用于单个曲线
        • CurveName - 曲线的标签
        • CurveLine - DrawingVisual,将呈现实际曲线通过对样条函数的内部实现进行采样。
        • CurveEditPoints - 帆布保存所有编辑点
          • CurveEditPoint - 用户控件的一个编辑点
            • LeftTangent - 用户控件左切处理
              • LeftTangentThumb - 用于修改手柄
            • RightTangent - 用户控件的右切线处理
              • RightTangentThumb - 修改手柄
          • CurvePointCenter - 实际点的可视化,选择状态和插值类型。
            • CurvePointThumb - 拇指选择和周围

我知道拖动点,这是一个相当复杂的问题,我不要求实际执行。我感兴趣的是以下几个问题:

  1. 你能推荐任何教程或书籍,可以帮助我(我已经得到了画报WPF,WPF控件开发如虎添翼,和其他几个)
  2. 应该微量元素像切线是单独的用户控件?
  3. 什么容器最适合托管个人“曲线”,“EditPoints”和“切线”。现在,我使用Canvas和Canvas.SetLeft/SetTop来定位孩子,但是感觉“奇怪”。
  4. 我应该使用“形状”像Path或DrawingVisual-Classes来实现实际表示。路径很简单,但我关心的是数百个CurvePoints的性能。
  5. 我应该使用变换来旋转切线,还是可以在文件后面的代码中做一些三角测量运算?
  6. 这个结构是否有意义,还是你提出了一个完全不同的方法?
+0

我不能说技术细节,但只是基于你提供的细节 - 以及你已经给出的想法 - 我想说你应该开始,看看你最终结束了。你可以开始“真正的”,并在精神上为重做做好准备,或者做一些概念证明/尖峰来巩固“承诺”之前的一些细节。 – 2011-03-14 01:30:03

+0

谢谢。我知道,学习WPF的唯一方法就是通过做。但我已经了解到,与WPF相比,有更多方法可以做到“错误”,而不是更小,更快,更易维护的预期解决方案,但是(这是我的问题的原因)需要我从来没有听说过的WPF功能。 所以我已经想通了,将曲线作为ListBox和KeyPoints作为具有特殊控制模板的Items实现可能会更好。这听起来像是会为我处理诸如选择和虚拟化之类的事情。 – pixtur 2011-03-14 07:56:25

回答

6
  1. 你似乎有合适的工具在手,WPF Unleashed是优秀的,但我猜你有一个已经。

  2. 使个人用户控件在其中一起案件:

    • 您使用的是相同的XAML所有的地方(干)
    • 你的XAML文件变得太大(得到一些组件出)
    • 需要从某些类
  3. 这取决于你要多少代码隐藏继承。
    如您在评论中所建议的那样,您可以使用ItemsControl作为容器,用于需要在多个项目之间进行选择的位置。所以这也可以在Curves级别上完成,而不仅仅是在曲线上的点级。根据你想要如何处理实际线条和曲线的绘制,你甚至可以有一个ItemsControl。 (注意:尽管你不会有虚拟化,因为你的物品不会有一个恒定的高度)

  4. 路径是好的,有数百个CurvePoints。如果你有10.000,我会说你可能会遇到问题。
  5. 无法想象应该如何在这里使用一个转换,也许在一个Adorner中。
  6. 你的结构看起来不错。你将能够实现所有这一切。我会建议,但我怎么会这样做:

首先使用MVVM。

  • CurveEditor
    列表框(面板=帆布)(的ItemsSource =曲线)(的ItemTemplate = CurveControl)

  • CurveControl

    • 画布(背景=透明)< =我不确定如果标准是白色的,但你不想重叠其他曲线...
      • CurveName
      • 列表框(面板=画布(背景=透明))(的ItemsSource = CurveParts)
      • 列表框(面板=画布(背景=透明))(的ItemsSource = CurvePoints)(的ItemTemplate => EditPointControl)
  • EditPointControl

    • 帆布
      • 拇指(模板=椭圆)(名称= CenterHandle)(与某些Visualstates的选择和切线的隐藏)
      • 拇指(模板=椭圆)(名称= LeftHandle)
      • 拇指(模板=椭圆)(名称= RightHandle)
      • 线(绑定X/Y至森特尔庞特和LeftHandlePoint)
      • 线(绑定X/Y至森特尔庞特和RightHandlePoint)

我已经声明为ListBox设置ItemTemplate。不过,您可以根据需要设置列表框的样式(我认为标准样式包含边框,您可能希望删除该边框或设置边框大小= 0),并设置为代替ItemTemplate ItemContainerStyle并绑定到IsSelected,以便控制IsSelected ViewModel(我的意思是看here)。

因此视图模型看起来是这样的:

- 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,并重新计算你暴露的路径。

我可能会改善它,因为我走了,但这是我的第一次猜测。

有一些细节可能需要注意。例如:大拇指的风格可能是中间的一个可见的圆圈,而在背景=透明的情况下,大概是一个看不见的圆圈。这样,你可以将可见圆圈缩小,但让用户在小圆圈周围的区域使用圆圈。

编辑

这里是拇指为例:

 <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。

+0

说实话,我不太确定,在StackOverflow中提出这样的问题是否有意义。但是,不,我对这个深度答案绝对惊讶!它可能会花费我一段时间来完成详细的消化。有几个课程和我从未听过的概念。 ESP。 MVVM的东西很有趣。 我会尝试给你建议的结构,看看我得到多远。我相当肯定这会让我在另一个层面上理解WPF。谢谢! – pixtur 2011-03-14 21:41:36

+0

一个问题:为什么要将CurveEditPoint中心的视觉表示推送到拇指模板中?我无法理解这个原因。 – pixtur 2011-03-14 22:06:31

+0

@pixtur看到我的编辑。原因是:你需要重新设置拇指,为什么不立即在那里放置你想看的东西?! – 2011-03-15 10:13:01