我目前正在從事我的第一個 Prism 專案,但遇到以下問題:
我的專案包含兩個區域,一個 ContentRegion 和一個 MenuRegion,每個區域都應該訪問相同的 ViewModel 實體。
在 MenuRegion 中,活動 ViewModel 的一些方法應該是可選擇的。在下面的示例中,應該能夠從 ContentRegion 和 MenuRegion 觸發 Save 方法。
問題是我最初創建了兩個不同的 ContentAViewModel 實體,并且選單的 Save 方法無法訪問我的 ContentRegion 的當前資料。
我已經嘗試將 ViewModels 注冊為單例,但不幸的是這不起作用并且可能違反了 Prism 原則。
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
moduleCatalog.AddModule<ModuleA>();
}
}
public class MainWindowViewModel : BindableBase
{
private readonly IRegionManager _regionManager;
public MainWindowViewModel(IContainerExtension container, IRegionManager regionManager)
{
_regionManager = regionManager;
_regionManager.RequestNavigate("ContentArea", "ContentAView");
_regionManager.RequestNavigate("MenuArea", "MenuA");
}
}
<Window
x:Class="PrismProject.Views.MainWindow"
xmlns:prism="http://prismlibrary.com/"
AllowsTransparency="True"
Background="Transparent"
xmlns:core="clr-namespace:PrismProject.Core;assembly=PrismProject.Core"
ResizeMode="CanResizeWithGrip"
WindowStyle="None">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--[...]-->
<ContentControl
Grid.Column="1"
Panel.ZIndex="10"
prism:RegionManager.RegionName="{x:Static core:RegionNames.MenuRegion}" />
<!--[...]-->
</Grid>
<ContentControl
Grid.Row="1"
prism:RegionManager.RegionName="{x:Static core:RegionNames.ContentRegion}" />
</Window>
public class ModuleA : IModule
{
private readonly IRegionManager _regionManager;
public CalculatingModule(IRegionManager regionManager)
{
_regionManager = regionManager;
}
public void OnInitialized(IContainerProvider containerProvider)
{
_regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(ContentAView));
_regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(ContentBView));
_regionManager.RegisterViewWithRegion(RegionNames.MenuRegion, typeof(MenuA));
_regionManager.RegisterViewWithRegion(RegionNames.MenuRegion, typeof(MenuB));
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
//containerRegistry.RegisterSingleton<ContentAViewModel>();
//containerRegistry.RegisterSingleton<ContentBViewModel>();
ViewModelLocationProvider.Register<MenuA, ContentAViewModel>();
ViewModelLocationProvider.Register<MenuB, ContentBViewModel>();
}
}
public class ContentAViewModel: RegionViewModelBase
{
private readonly IRegionManager _regionManager;
public ContentAViewModel(IRegionManager regionManager) : base(regionManager)
{
SaveCommand = new(Save);
_regionManager = regionManager;
}
private void Save()
{
// logic
}
}
<UserControl
x:Class="PrismProject.Modules.ModuleA.Views.ContentAView"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid>
<Button
Command="{Binding SaveCommand}"
Content="Save"/>
<!--[...]-->
</Grid>
</UserControl>
<UserControl
x:Class="PrismProject.Modules.ModuleA.Menus.MenuA"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid>
<Menu>
<MenuItem
Command="{Binding SaveCommand}"
Header="Save"/>
<!--[...]-->
</Menu>
</Grid>
</UserControl>
如何在僅使用 ViewModel 的一個實體時將相同的 ViewModel 分配給多個視圖?
uj5u.com熱心網友回復:
我必須做同樣的事情。我在他的一個在線視頻中使用了 Brian Lagunas(Prism 的作者之一)提出的一種優雅的技術。來自一個優秀的教程網站,我不會命名,以免聽起來像一個騙子,但如果你谷歌“棱鏡問題和解決方案:加載依賴視圖”你會找到它。我強烈推薦觀看。但我會在這里給你這個技術的概要。
(就我而言,我的每個模塊的主視圖都需要與“工具”視圖共享其視圖模型,而 Prism 需要自動將其放入我定義的另一個區域)
PageToolAttribute創建一個使用“companion”視圖名稱的屬性(我稱之為)- 將該屬性應用于應該與伴隨視圖共享其視圖模型的“主”視圖。提供名稱“您希望出現在其他 Prism 區域中的伴隨視圖。
- 創建一個派生自 Prism 類的
RegionBehavior類,該類(在其覆寫中OnAttach)掛鉤到 Prism 區域的ActiveViews.CollectionChanged事件。在處理程式中,您詢問新添加的視圖是否具有PageToolAttribute. - 如果新添加的視圖確實支持該屬性,則您的事件處理程式獲取其名稱并創建它的新實體,將其與
DataContext視圖(即您要共享的視圖模型)相同,最后導航到另一個區域新添加的視圖。 - 最后,在您的 Prism Aap 中,您覆寫該
ConfigureDefaultRegionBehaviors函式并呼叫AddIfMissing(在提供的 上IRegionBehaviorFactory)以添加您的屬性。
需要學習的內容很多,需要深入了解 Prism,但代碼量卻少得驚人,而且它的作業原理就像一個冠軍。我現在有 7 個不同的模塊,每個模塊都有自己的配套“工具”視圖,每次都可以導航。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/440643.html
