簡體   English   中英

WPF棱鏡 - 使用棱鏡區域有什么意義?

[英]WPF Prism - What is the point of using Prism Regions?

我只是想知道地區的意義。 我想我不明白他們解決的問題

例如,我看到很多人使用區域作為導航區域,但是為什么不只是將ItemsControl綁定到ObservableCollection而不是具有區域並將不同的導航元素加載到該區域?


一個現實世界的例子,它的使用/好處超過替代品將搖滾!

將RegionManager與EventAggregator進行比較,您將看到它的優勢......

EventAggregator允許不同的組件發布/訂閱事件而不相互耦合。 RegionManager也是如此......您可以將視圖加載到某個區域,而無需其他視圖知道其中發生了什么。 它將你的觀點彼此分離......這並不是說每個觀點都應該彼此不知道......有時候觀點應該知道另一個觀點。


看看Microsoft Outlook(注意:我在這里制作東西,包括名稱,因為Outlook 不是用WPF編寫的,而是用C ++編寫的):

主UI將具有以下區域:

  • MenuRegion
  • NavigationRegion
  • ContentRegion
  • SideRegion

區域在標准控件上定義(因此您仍需要標准控件),更具體地說,ItemsControl,ContentControl和Selector開箱即用(您可以將其他控件擴展為“區域支持”)。 它們允許另一部分代碼通過將適當的視圖解析並加載到這些區域來管理區域。 基本上,要保持事物分離。

你是主UI,不需要知道你的應用程序的一切 ; 相反,它只需要知道它有一個菜單,導航,內容和側面區域。 實際放置在區域中的哪些視圖無關緊要。 現在,這並不意味着每個視圖都應該彼此分離。 我稍后會談到的。

那么,它實際上如何解耦? 這是一個場景:單擊導航控件中的日歷圖標。 那么當你這樣做會發生什么?

  1. NavigationView - Button(Icon)綁定到ICommand ,因此它調用ExecuteLoadCalendar()函數。
  2. NavigationViewModel - ExecuteLoadCalendar()函數使用EventAggregator來宣告用戶正在嘗試啟動日歷。
  3. ContentController - ContentController訂閱了LoadCalendarAggregateEvent ,因此執行了。 在這里,它使用IRegionManager和區域名稱解析/激活CalendarViewCOUPLED )。 它應該通過抓取ICalendarView而不是CalendarView

在整個過程中,除了ContentControllerCalendarView / ICalendarView之外,每個部分都是分離的。 當然,你可以說通過ICommand和函數, NavigationView / NavigationViewModel 有點了解CalendarView / CalendarViewModel 好吧,“有點”與“他們做”不一樣,因為代碼隱藏和視圖模型代碼永遠不應該引用實際的CalendarView / CalendarViewModel對象。

此外,我們可以通過使執行泛型來刪除“種類”。 它不具有ExecuteLoadCalendar()函數,而是具有LoadContent(NavigationItem item)函數,其中AggregateEvent有效內容是某種類型的標識,例如, item.Name (String) (從DB,XML等加載)說他們點擊了“日歷”。 ContentController使用相同的數據來解析“Calendar”而不是ICalendarView (因為它實際上不應該關心在ContentRegion解析/激活的接口/類型 - 它只需要一個Object來激活)。 我使用MEF,因此可以使用以下代碼塊實現:

[Export("Calendar")]
public class CalendarView : UserControl, ICalendarView { }

那么,觀點能相互了解嗎? 是! 例如,我的EmailUserControl有一個搜索欄/電子郵件列表以及一個預覽窗格。 這兩個控件可以是EmailListUserControl ,它由搜索欄和ItemsControl組成,還有EmailContentUserControl ,它只是所選電子郵件的預覽窗格。 它們必須是單獨的控件嗎? 不,但如果他們是,那么我們可以在單獨的窗口中打開電子郵件時重復使用EmailContentUserControl 因此,這是一個示例,其中EmailUserControl耦合到2個不同的視圖( EmailListUserControlEmailContentUserControl )。


為什么這與其他方法更好/不同:它將視圖彼此分離(並防范需要了解視圖的視圖模型)。

區域允許您在程序中定義為特定目的而存在的位置。 例如,您可能有一個菜單區域或頁腳區域。 然后,您可以將這些特定區域的Views / ViewModel分離到它們自己的程序部分。

因此,不是讓ApplicationViewModel包含MenuViewModelFooterViewModel屬性,並讓View將每個部分綁定到這些屬性,而是為菜單和頁腳設置單獨的ViewModel,而ApplicationViewModel只處理內容。 這是分離應用程序中某些邏輯邊界的更好方法。

我個人認為地區過度使用和濫用。 我幾乎從不使用它們,除非我有一些與我的應用程序代碼的其余部分無關的Header或Footer。 它們也主要用於View-First開發,我更喜歡ViewModel-First。

區域啟用的場景

我瀏覽了這篇文章以獲得答案: http//www.developmentalmadness.com/archive/2009/10/14/mvvm-and-prism-101-ndash-part-3-regions.aspx

據我所知,Region功能旨在在您既不是視圖也不是視圖模型的代碼中啟用View注冊/注入。

ContentPresenter控件為例。 如果您使用它而不是Region,則視圖模型必須返回具體視圖,以使主視圖與其子視圖保持不變。

如果您使用ItemsControl並將其綁定到視圖模型上的任意數據,則需要指定在主視圖上的DataTemplate中實例化哪些視圖。

使用Region,可以在Dependency Injection容器中將視圖注冊到Region。 視圖和相應的視圖模型都不需要知道將在運行時使用的具體視圖。 它將由容器注入。

這使您可以完全將主視圖與其子視圖的任何內容分離,而無需強制您的視圖模型了解有關這些子視圖的任何信息。

具體用例

這是多么有用,以及這將帶來哪些具體方案,我不確定。 我已經使用了帶有插件架構的ContentPresenter ,但我不確定它是否適合這個模型。 使用插件模型,您希望將視圖和視圖模型綁定在一起,因此這種方法無需任何操作。

我想如果你發現你有很多不相關的觀點並希望將它們分開,那么它會發揮最佳效果。 通過一次僅注入部分視圖和視圖模型,將集成測試彼此隔離可能很有用。

我正在抓住吸引人的真實世界用例:)在幾乎所有的情況下,你可以簡單地使用UserControl ,並且可以放棄整個動態注冊的事情,沒有真正的缺點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM