2010-04-07 35 views
41

WPF非常棒,因爲有很多方法可以實現您的目標。例如,根據我的理解,裝飾者可以向UI元素添加一些控件,但我認爲可以通過包含附加元素的自定義控件實現相同的行爲。我應該什麼時候使用裝飾者?

所以,我的問題是:什麼時候我應該更喜歡裝飾者更復雜(但我認爲更靈活)的自定義控件? 請考慮我正在廣泛使用MVVM模式,我想將命令綁定到其他元素。

特別是,我正在設計一個圖表設計器應用程序,我想添加連接點到我的形狀。另一個我應該在自定義控件和裝飾者之間做出決定的例子是一條顯示標籤自動定位以「跟隨」線條的線條。

謝謝

回答

68

與大多數情況下使用ControlTemplates相比,裝飾者需要更多的工作。如果您想要裝飾者提供的附加功能,請使用它們。否則使用ControlTemplates。

下面是裝飾器帶來的表的主要特點:

  1. 由於裝飾器是一個單獨的層,視覺可延伸超出佐餐元件,即使佐餐元件被限幅。
  2. 因爲裝飾物在單獨的圖層上,所以它們通常不會被AdornedElement容器或兄弟控件遮擋。
  3. 裝飾元素會自動通知裝飾元素的大小和位置的所有變化,從而可以對佈局變化做出響應,而這些變化在普通控件中不易實現。
  4. 裝飾者可以應用於面板和現有的控制,而無需對其模板或其他方式進行任何更改。這使得它們可以在任意控件上提供操作手柄或視覺反饋。
  5. 在很多情況下,您只會爲幾百或幾千個「活動」項目創建裝飾。使用ControlTemplates實現相同的功能可能會大大降低效率,如果您必須添加一個額外的面板到模板:模板的每一個instatiation將有額外的面板,而只有一個裝飾者。

下面是一些使用裝飾器的潛在成本的,而不是CONTROLTEMPLATES:

  1. 您必須編寫代碼來調用.GetAdornerLayer().Add()和管理的裝飾器
  2. 必須在一生或者爲您的Adorner編寫渲染代碼或添加代碼以包含Control作爲裝飾的子項,以便您可以使用它的ControlTemplate
  3. 您通常會在鱈魚中執行自定義度量/排列計算E(除非您使用的裝飾器內的控件模板)
  4. 您需要轉發RoutedEvents到AdornedElement,如果你希望他們由目標控制處理
  5. 你需要添加一個DataContext="{Binding AdornedElement.DataContext}",如果你想使DataContext跨越
  6. 似乎在每個佈局過程中都會掃描可見的Adorner,因此同時在屏幕上顯示數千個裝飾器可能會導致明顯的速度下降。 (普通視覺效果只有在直接影響它們的東西發生變化時纔會調用它們的度量/排列代碼。)
  7. Having more than 144 adorners is not supported,因此如果有任何接近此限制的風險,則控件模板更合適。

在您的特定示例中,沒有明確的正確答案。

  • 我傾向使用一個控件模板的連接點,因爲你大概會需要一種方法來指定連接點的位置,和控件模板已經定義佈局項目本身。另一方面,如果連接點信息是數據驅動的並且只出現在活動控件上(或者控件被拖動),則使用裝飾器可以更好地獲得性能優勢並簡化各個ControlTemplates。

  • 如果線條只是簡單的直線,而自動定位的標籤可能非常適合從度量/排列計算的角度來看裝飾者,但是如果您一次可能會有一萬個可見的線條,會關注性能。

不知道更多關於您的應用程序,很難說比這更多。

+3

非常感謝,這是一個很好的完整答案。 該應用程序是一個UML設計器,所以我不認爲我會有太多的連接;無論如何,通常它們不是直線。 – fra 2010-04-12 05:05:27

相關問題