2011-06-13 46 views
2

我最近爲我的公司開發了一個繪圖組件,其中包含一個Canvas,通過它可以使用點擊拖動來繪製某些形狀。對於每一個形狀,我在它的AdornerLayer上放置了兩個裝飾物:一個用於增加命中檢測(基本上是一個透明的矩形,它將超出形狀的邊界幾個像素),另一個用於調整大小(角落上的四個拇指控制)。WPF裝飾者有什麼意義?

但是,當執行組件的一些功能時,我遇到了很多問題,所有與裝修有關的問題。

  • 他們將所有預覽事件,因爲他們是在另一可視化樹比畫布本身,那是意外,但我找到了一個解決辦法,即使我不喜歡那麼多。使用AdornerDecorator並沒有解決這個問題,我實施的選擇裝飾者是預覽事件的黑洞。當我對Canvas上的形狀執行z-index操作(發送回來,到達前面等)時,它可以正常使用Panel.SetZIndex,正如你所期望的那樣。但是,裝飾者在另一個視覺樹上!所以他們沒有受到影響,而選擇裝飾師仍然在所有其他形狀之上,即使這些形狀在選擇裝飾者正在檢測到的形狀之上。例如: Shape1,SelectionAdorner1。 Shape2,SelectionAdorner2。 Shape1位於Shape2的頂部(稍後添加到畫布上),因此它與其重疊。因此點擊它將被SelectionAdorner1檢測到。我操縱ZIndex將其發回,現在Shape2位於頂部並與Shape1重疊。我點擊Shape2的頂部,但點擊是由SelectionAdorner1而不是SelectionAdorner2檢測到的。 這特別煩人。所以,顯然自Adorners在另一個視覺樹上,他們不尊重ZIndexes。我試圖通過在形狀的ZIndex和它的SelectionAdorner的ZIndex之間創建一個DataBinding(並且通過手動設置)來解決它。但是這並沒有解決問題。改變Adorners的ZIndex並不影響它們在屏幕上的顯示方式,也許我錯過了一些東西,但它不應該真的這麼難,因爲Adorners應該是爲了讓事情變得更容易。我能想出的唯一解決方案是手動刪除所有裝飾者,然後再一次手動添加它們,最後添加應該位於最上面的裝飾者。這是遲緩的,但它的工作。

  • 接下來,裝飾者不尊重ClipToBounds!我在Canvas中設置了ClipToBounds = true我正在做繪圖,它運行良好,但該死的裝飾者仍然會工作!對此的解決方案是相對無痛的,我只是在每個Shape的頂部添加了一個AdornerDecorator。這不是IMO的理想解決方案,但它足夠簡單。

  • 裝飾者並不總能很好地對其裝飾元素上執行的LayoutTransforms做出反應。我有一個實現縮放和平移功能的畫布頂部的面板。它使用動畫來縮放和平滑。但是使用動畫導致我的裝飾者變得猿猴!第一次縮放它們會忽略調整大小並保持相同的大小和位置,在第二次縮放時,它們將縮放到以前的大小的裝飾元素。這沒有任何意義!唯一的解決辦法我能找到的禁用動畫,這令人欣慰工作

我不太記得它的其他問題我有,但這是綽綽有餘MAME我想知道裝飾器的用處,我我認真考慮不在下一個項目中使用它們,這與我描述的類似。

那麼,誰能告訴我什麼可能是使用這些看似有用但令人難以置信的惱人的東西的優點?

謝謝。

回答

6

我認爲你已經知道你的問題的答案。它們在某些方面節省時間,並在其他方面造成問題。如果您要使用各種UserControl編寫此設計器行爲,則會發現自己編寫了大量樣板控件類來包裝您實際想要編輯的元素。另一方面,如果您嘗試編寫單獨的編輯控件並智能地覆蓋它們,您將編寫樣板代碼以保持其位置和大小同步。你採用的方法,使用裝飾,導致了很多(相當模板)的代碼來管理事件。

雖然裝飾者可能不是這個特定任務的最佳工具,但它們仍然是其他更簡單任務的有用工具。我最近寫了一個類似的「設計表面」,裝飾品是天賜的兩件作品:

  1. 拖放行爲。當我拖動不同的元素時,他們需要有不同的視覺預覽;使用自定義裝飾器和數據模板非常容易實現。
  2. 選擇矩形或「套索」。當您在Windows桌面上按住鼠標左鍵並拖動指針時,可以看到類似的東西。它創建了一個可以選擇多個元素的半透明框。我能夠幾乎立即用裝飾圖層創建此行爲,而創建自己的自定義控件導致了大量不必要的記帳。

我想你在你的項目中發現的是,你可能一直在使用裝飾者來嘗試和完成太多。但不要把寶寶扔出去洗澡 - 它們在某些情況下仍然非常有用。

+0

你是非常正確的,你可能對我有用的地方的例子很有趣,特別是因爲我會需要類似的東西來拖放,謝謝你的提示。 – 2011-06-14 02:24:33