【发布时间】:2017-10-20 16:33:34
【问题描述】:
我正在使用 Prism 6 构建一个包含多个不同模块的应用程序。这是一个简单的按钮菜单,每个按钮将主要内容区域导航到不同的动态发现视图。不幸的是,我发现自己对主菜单按钮进行了硬编码,这显然不是我想要的。
我想要的是从已为我的类别注册的所有视图的列表中动态构建单选按钮的 ItemsControl。但我不知道如何编写要求 Prism 提供此类列表的 ViewModel 属性。
此外,我希望我的整体方法是合理的。
为了说明,现在我有几个功能显示,每个都在自己的模块中实现。
- 用于显示来自相机的实时视图和捕获图像的模块
- 用于浏览捕获图像库的模块
- 为简洁起见忽略其他内容
在我的主视图 XAML 中,左侧有 DockPanel 中的按钮,右侧有区域(ContentControl“Main”)中的视图内容。这是 XAML 精简了一点。
<DockPanel >
<Border MinWidth="50"
DockPanel.Dock="Left"
>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<Style TargetType="{x:Type RadioButton}"
BasedOn="{StaticResource CategoryButton}">
<Setter Property="GroupName" Value="MainGroup"/>
<Setter Property="IsChecked">
<Setter.Value>
<MultiBinding Converter="{StaticResource ObjectEqualsConverter}" Mode="OneWay">
<Binding Path="DataContext.ActivePageName"
RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
<Binding Path="CommandParameter" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<RadioButton Command="{Binding NavigateCmd}"
CommandParameter="CaptureView"
Margin="5" Content="Capture"
/>
<RadioButton Command="{Binding NavigateCmd}"
CommandParameter="LibraryView"
Margin="5" Content="Explore"
/>
</StackPanel>
</Border>
<!--
Content is in the region named "Main". Modules register their own page
views and we navigate this region to show them as the user clicks the
page buttons.
-->
<ContentControl x:Name="Page"
prism:RegionManager.RegionName="{x:Static ga:Regions.Main}"
/>
</DockPanel>
</Window>
我的主视图模型
public class MainWindowVm : BaseVm
{
private readonly IRegionManager _regionManager;
private readonly IUnityContainer _container;
private readonly IModuleCatalog _catalog;
private readonly IEventAggregator _aggregator;
public MainWindowVm(
IRegionManager rm,
IUnityContainer container,
IModuleCatalog catalog)
{
NavigateCmd = new Prism.Commands.DelegateCommand<string>(Navigate);
_regionManager = rm;
_container = container;
_catalog = catalog;
}
public string CurrentView => (string)_regionManager?.Regions[Regions.Main]?.ActiveViews?.FirstOrDefault()?.ToString() ?? "";
public Prism.Commands.DelegateCommand<string> NavigateCmd { get; private set; }
public void Navigate(string path)
{
_regionManager.RequestNavigate(Regions.Main, path, NavigationCompleted);
}
private void NavigationCompleted(NavigationResult nr)
{
RaisePropertyChanged("");
}
public string ActivePageName
{
get
{
// HACK: Currently I'm taking the fully qualified name of the
// current view (e.g. "MyCompany.LibraryModule.LibraryView") and just
// chopping off all namespaces to get the basic, unqualified
// view name (e.g. "LibraryView") which I am blithely assuming
// will perfectly match one of the Page buttons on the main
// window. This really needs to be improved and generalized...
var name = CurrentView;
var i = name.LastIndexOf('.');
if (-1 != i)
name = name.Substring(i+1);
return name;
}
}
};
我的模块使用 RegisterTypeForNavigation 注册他们的视图。例如:
public class LibraryModule : IModule
{
private readonly IRegionManager _regionManager;
private readonly IUnityContainer _container;
public LibraryModule(IRegionManager regionManager, IUnityContainer c)
{
_regionManager = regionManager;
_container = c;
}
public void Initialize()
{
_container.RegisterTypeForNavigation<LibraryView>();
}
}
根据我的设置,有没有一种简单的方法可以实现这一点。我应该改用其他注册/导航方法吗?
Prism 发生了如此巨大的变化,所有样本似乎都有些过时了,所以我不知道该怎么做
【问题讨论】: