WPF Prism(五)Navigation

WPF Prsim(一)Region
WPF Prism(二)Module
WPF Prism(三)ViewModelLocator
WPF Prism(四)MVVM
WPF Prism(五)Navigation
WPF Prism(六)Dialog

一、使用场景

在普遍的业务场景当中,必不可少的是页面切换,而Prism就可以使用Navigation功能来进行页面导航,在不同的场景当中会有各种用法,例如在切换页面验证、传递参数、返回上一页、返回下一页等功能。

二、导航的使用

2.1 注册显示区域(region)

这个在前面章节已做详细介绍不再赘述。

2.2 注册导航页面(View)

之前的介绍中我们一般是将一个View指定到一个region中。而现在我们需要将多个View注册到导航中。例如我们现在有两个子模块(ViewAModule和ViewBModule),我们分别注册导航界面:

    public class ViewAModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation(typeof(ViewA.Views.ViewA), "ViewA");
        }
    }
    public class ViewBModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {

        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation(typeof(ViewB.Views.ViewB), "ViewB");
        }
    }

注意这一段代码:

containerRegistry.RegisterForNavigation(typeof(ViewB.Views.ViewB), "ViewB");

这就代码就是注册导航页面的,其中第一个参数是View的类型,第二个参数是ViewName(可省略,则默认为View类型的类名)。当然,这句代码也可以在App类中的重写函数中实现。

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation(typeof(ViewA.Views.ViewA), "ViewA");
            containerRegistry.RegisterForNavigation(typeof(ViewB.Views.ViewB), "ViewB");
        }

然后我们在主界面上添加两个按钮用于导航:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <StackPanel
            Grid.Row="0"
            Margin="10"
            Orientation="Horizontal">
            <Button
                Width="40"
                Height="30"
                Margin="40,0,40,0"
                Command="{Binding NavigationCmd}"
                CommandParameter="ViewA"
                Content="ViewA" />
            <Button
                Width="40"
                Height="30"
                Margin="40,0,40,0"
                Command="{Binding NavigationCmd}"
                CommandParameter="ViewB"
                Content="ViewB" />
        </StackPanel>
        <ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" />
    </Grid>

在MainViewModel中我们进行了一些数据的绑定:

    public class MainWindowViewModel : BindableBase
    {
        public DelegateCommand<string> NavigationCmd { get; private set; }
        private IRegionManager region;
        public MainWindowViewModel(IRegionManager regionManager)
        {
            this.region = regionManager;
            NavigationCmd = new DelegateCommand<string>(Navigation);
        }

        private void Navigation(string page)
        {
            region.RequestNavigate("ContentRegion", page);
        }
    }

注意这一段代码:

region.RequestNavigate("ContentRegion", page);

第一个参数是RegionName,第二个参数是我们前面注册的ViewName。其实它还有很多重载函数,还有另外两个参数Action navigationCallbackNavigationParameters navigationParameters

2.3 导航完成后的回调

        private void Navigation(string page)
        {
            region.RequestNavigate("ContentRegion", page,NavigationCallback);
        }

        private void NavigationCallback(NavigationResult result)
        {
            Console.WriteLine(result.Context.Uri);
            Console.WriteLine(result.Error.Message);
            Console.WriteLine(result.Result.Value);
        }

请求导航完成的回调函数。

2.4 请求导航时的参数

        private void Navigation(string page)
        {
            NavigationParameters parameters= new NavigationParameters("param1");

            region.RequestNavigate("ContentRegion", page,NavigationCallback, parameters);
        }

这个参数有什么用,怎么用,我们在后面详说。

2.5 INavigationAware

我们导航切换界面到底是一个什么过程呢?这样我们需要了解INavigationAware接口。该接口有三个方法需要实现。

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            throw new NotImplementedException();
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            throw new NotImplementedException();
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            throw new NotImplementedException();
        }
  • OnNavigatedTo: 导航到当前页面前, 此处可以传递过来的参数以及是否允许导航等动作的控制
  • IsNavigationTarget: 是否创建新示例。为true的时候表示不创建新示例,页面还是之前的;如果为false,则创建新的页面。
  • OnNavigatedFrom: 导航离开当前页面前。

传递参数示例:

  var parameters = new NavigationParameters();
            parameters.Add("person", person);
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            var person = navigationContext.Parameters["person"] as Person;
            if (person != null)
                SelectedPerson = person;
        }

注意,这个接口应该由ViewModel来继承。

所以一个完整的导航请求的过程如下:

RequestNavigate
OnNavigatedFrom
IsNavigationTarget
ResolveView
OnNavigatedTo
NavigateComplete

2.6 IConfirmNavigationRequest

该接口继承自INavigationAware,所以,它多了一个功能:允许用户针对导航请求进行拦截。同时也需要多实现一个方法:

        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
        {
            throw new NotImplementedException();
        }
    public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
    {
        bool result = true;

        if (MessageBox.Show("Do you to navigate?", "Navigate?", MessageBoxButton.YesNo) == MessageBoxResult.No)
            result = false;
        
        //true则同意 false则拒绝
        continuationCallback(result);
    }

所以这个接口的执行流程为:

RequestNavigate
ConfirmNavigationRequest
OnNavigatedFrom
ContinueNavigationProcess

2.7 IRegionNavigationJournal

导航日志,其实就是对导航系统的一个管理功能,理论上来说,我们应该知道我们上一步导航的位置、以及下一步导航的位置,包括我们导航的历史记录。以便于我们使用导航对应用程序可以灵活的控制。

IRegionNavigationJournal接口有如下功能:

  • GoBack() : 返回上一页
  • CanGoBack : 是否可以返回上一页
  • GoForward(): 返回后一页
  • CanGoForward : 是否可以返回后一页
        IRegionNavigationJournal _journal;
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            _journal = navigationContext.NavigationService.Journal;
        }

我们可以在OnNavigatedTo函数中得到IRegionNavigationJournal的实现,然后就可以使用相应的方法。

三、InvokeCommandAction

直接由控件的事件触发,然后转化为Command。

   xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
   <ListBox x:Name="_listOfPeople" ItemsSource="{Binding People}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <prism:InvokeCommandAction Command="{Binding PersonSelectedCommand}" CommandParameter="{Binding SelectedItem, ElementName=_listOfPeople}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </ListBox>

上面的一种方式是传送一个其他的参数给命令。是否可以直接将事件参数传递给命令呢?

        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        <ListBox Grid.Row="1" Margin="5" ItemsSource="{Binding Items}" SelectionMode="Single">
            <i:Interaction.Triggers>
                <!-- This event trigger will execute the action when the corresponding event is raised by the ListBox. -->
                <i:EventTrigger EventName="SelectionChanged">
                    <!-- This action will invoke the selected command in the view model and pass the parameters of the event to it. -->
                    <prism:InvokeCommandAction Command="{Binding SelectedCommand}" TriggerParameterPath="AddedItems" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ListBox>
 public IList<string> Items { get; private set; }

        public DelegateCommand<object[]> SelectedCommand { get; private set; }

        public MainWindowViewModel()
        {
            Items = new List<string>();

            Items.Add("Item1");
            Items.Add("Item2");
            Items.Add("Item3");
            Items.Add("Item4");
            Items.Add("Item5");

            // This command will be executed when the selection of the ListBox in the view changes.
            SelectedCommand = new DelegateCommand<object[]>(OnItemSelected);
        }

        private void OnItemSelected(object[] selectedItems)
        {
            if (selectedItems != null && selectedItems.Count() > 0)
            {
                SelectedItemText = selectedItems.FirstOrDefault().ToString();
            }
        }

代码中Command的参数是object[]类型,我也不知道为什么。。。。请大佬告知!!!

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: WPF Prism文档是指关于Prism框架的详细说明和使用指南的文件集。Prism是一种基于WPF(Windows Presentation Foundation)的开发框架,它旨在帮助开发人员设计和构建复杂的、可扩展的企业级WPF应用程序WPF Prism文档通过提供清晰的指导和实例,帮助开发人员学习和理解如何正确地使用Prism框架。这些文档通常包含Prism框架的基本概念、设计模式和最佳实践。在这些文档中,开发人员可以了解到如何将应用程序分解为模块,如何使用依赖注入来管理应用程序的组件和模块之间的依赖关系,以及如何使用事件聚合器进行模块间的通信等等。 此外,WPF Prism文档还提供大量的示例代码和实用的代码片段,帮助开发人员快速理解和运用Prism框架的功能。这些示例代码涵盖了Prism框架各个方面的应用,包括注册模块、导航和区域管理、命令和互动、模块间通信等等,以满足不同开发需求的应用程序场景。 通过阅读WPF Prism文档,开发人员可以更好地理解Prism框架的核心概念和设计原则,从而更高效地构建可维护、可扩展的WPF应用程序。这些文档也可以作为学习和培训的参考资料,帮助新手快速入门,并且帮助有经验的开发人员进一步提升他们的技术水平。 总之,WPF Prism文档是一份宝贵的资源,为开发人员提供了全面的指导和实例,帮助他们掌握和运用Prism框架,以构建高质量的WPF应用程序。 ### 回答2: WPF Prism文档是指Prism开源框架的相关文档。Prism是一种用于构建模块化、可扩展、高效、可测试且易于维护的WPF应用程序的框架。Prism的文档提供了详细的指导和说明,帮助开发人员快速上手并正确地使用Prism框架。 WPF Prism文档通常包含以下内容:框架的介绍和概述,包括它的设计理念、优势以及使用场景;安装和配置指南,指导开发人员如何在他们的项目中引入和配置Prism;架构和模块化概念的介绍,帮助开发人员理解Prism框架的核心思想;关于如何创建和组织模块的指导,包括如何定义和加载模块,如何使用导航和呈现模块的方式等;还包括关于依赖注入、命令和事件聚合器等核心概念的详细解释和用法示例。 此外,WPF Prism文档还通常包含一些实用的示例代码,以帮助开发人员更好地理解和运用框架的特性和功能。这些示例可以涵盖从简单的模块创建到复杂的UI导航和模块通信的各个方面。 总而言之,WPF Prism文档通过提供详细的指南、解释和示例代码,帮助开发人员了解和使用Prism框架,以便有效地构建出高质量、可维护和可扩展的WPF应用程序。 ### 回答3: WPF Prism文档是Prism框架的官方文档,用于帮助开发人员理解和使用Prism框架。Prism是一个用于开发模块化、可扩展和可重用的WPF应用程序的开源框架。 WPF Prism文档包含了Prism框架的完整说明和指南,涵盖了框架的核心概念、设计原则和使用方法。文档详细介绍了Prism框架的各个组件,如模块化、导航、命令、事件聚合器等,并提供了示例代码和详细解释,帮助开发人员快速上手和理解框架。 在WPF Prism文档中,开发人员可以了解到Prism框架的优点和适用场景,了解如何将Prism集成到自己的WPF应用程序中,并利用框架提供的功能和工具来简化开发过程。文档还介绍了Prism的相关概念和模式,如依赖注入、解耦和松耦合等,帮助开发人员遵循最佳实践和设计原则,构建出高质量和可维护的应用程序。 除了框架的详细说明和指南,WPF Prism文档还包含了一些常见问题和解决方案,帮助开发人员解决在使用Prism框架时遇到的困难和问题。文档还提供了一些扩展和相关资源的链接,帮助开发人员深入学习和探索Prism框架的更多功能和扩展。 总之,WPF Prism文档是Prism框架的权威指南,对于希望使用Prism框架开发WPF应用程序的开发人员来说,它是一个不可或缺的参考资料。通过学习和理解WPF Prism文档,开发人员能够更加高效和灵活地开发出优秀的WPF应用程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值