【问题标题】:Prism 6 Navigation and dynamically discovering viewsPrism 6 导航和动态发现视图
【发布时间】: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 发生了如此巨大的变化,所有样本似乎都有些过时了,所以我不知道该怎么做

【问题讨论】:

    标签: c# wpf mvvm prism


    【解决方案1】:

    Prism 发生了如此巨大的变化,所有样本似乎都有些过时了,所以我不知道该怎么做

    实际上,用于 WPF 的 Prism 多年来一直没有变化,并且所有当前示例都是最新的。所以,不知道你是根据什么做出这个声明的。

    你在想这一切都是错的。您正在注册您的视图,然后尝试询问 Prism 视图名称是什么。相反,实际发生的是您告诉 Prism 您拥有哪些视图名称并相应地进行注册。您已经拥有数据,只需将其存储在您可以要求的地方。您最好拥有某种类型的 ViewRegistrationService 来管理注册的视图名称并将它们添加到您的 ItemsControl 可以绑定到的集合中。该服务应该是单例的。

    【讨论】:

    • 这个人自己的回答,谢谢!当我说它已经改变时,我说的是 4.0 到 5.0 到 6.x。我意识到那是几年,但我对这个和 Pluralsight 介绍视频比 6.x 更早。简而言之,我正在努力追赶。我的计划是通过搜索本地目录来改进此代码以发现我的模块(以及我的视图),在这种情况下,我不会提前知道我有什么。我猜想 Region Manager 就是那个“发现”服务,但我肯定会听取您的建议并创建自己的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多