2011-03-11 60 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