Prism

Prism

1. 介绍

Prism [ˈprɪzəm] 为 MVVM 思想开发框架之一。

WPF Prism 是微软提供的一个开源框架,旨在帮助开发人员构建复杂的、模块化和可维护的 WPF 应用程序。Prism 支持 MVVM 设计模式,模块化开发,以及依赖注入,并为 WPF 应用提供导航、事件管理和区域管理的功能。

Prism 的核心组件包括:

  1. 数据绑定(Data Binding):虽然 Prism 本身不提供数据绑定机制,但它与 WPF 和 Xamarin.Forms 的数据绑定框架紧密集成,可以轻松地将视图模型与视图进行绑定。

  2. 命令(Commands):Prism 提供了一种简化的方式来处理用户界面中的命令,如按钮点击事件。

  3. 依赖注入(Dependency Injection):Prism 提供了一个依赖注入容器,可以将应用程序的组件和服务进行解耦,从而提高代码的可测试性和可维护性。

  4. ‌区域(Region):是一个UI容器,用于动态加载和卸载不同的视图和组件。

  5. 导航(Navigation):Prism 提供了一个灵活的导航系统,可以定义视图之间的导航路径,并管理视图的生命周期。

  6. 模块化(Modularity):Prism 支持模块化设计,将应用程序分解成独立的模块,每个模块负责特定的功能,有助于减少应用程序的复杂性,并能够使开发和维护更加容易。

  7. 事件聚合器(Event Aggregator):这是一个松散耦合的事件发布/订阅机制,应用程序的不同部分之间进行通信,而不需要直接引用对方。

2. 快速入门

2.1 手动构建 Prism 项目

2.1.1 创建项目

2.1.2 项目结构
  1. 目录名称必须为 Models,ViewModels,Views。

  2. 将MainWindow.xaml、MainWindow.xaml.cs 移动到 Views目录中。命名空间添加 .Views。

  1. MainWindow.xaml

    <span style="background-color:#333333"><span style="color:#999977"><</span><span style="color:#7df46a">Window</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_WpfApp1.Views.MainWindow"</span>
            <span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
            <span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
            <span style="color:#7575e4">xmlns:d</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/expression/blend/2008"</span>
            <span style="color:#7575e4">xmlns:mc</span>=<span style="color:#d26b6b">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
            <span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_WpfApp1"</span>
            <span style="color:#7575e4">mc:Ignorable</span>=<span style="color:#d26b6b">"d"</span>
            <span style="color:#7575e4">Title</span>=<span style="color:#d26b6b">"MainWindow"</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"450"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"800"</span><span style="color:#999977">></span>
        <span style="color:#999977"><</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
            
        <span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
    <span style="color:#999977"></</span><span style="color:#7df46a">Window</span><span style="color:#999977">></span></span>
  2. MainWindow.xaml.cs

    <span style="background-color:#333333"><span style="color:#c88fd0">namespace</span> <span style="color:#8d8df0">Prism_WpfApp1</span>.<span style="color:#b8bfc6">Views</span>
    {
        <span style="color:#da924a">/// <summary></span>
        <span style="color:#da924a">/// MainWindow.xaml 的交互逻辑</span>
        <span style="color:#da924a">/// </summary></span>
        <span style="color:#c88fd0">public</span> <span style="color:#c88fd0">partial</span> <span style="color:#c88fd0">class</span> <span style="color:#8d8df0">MainWindow</span> : <span style="color:#b8bfc6">Window</span>
        {
            <span style="color:#c88fd0">public</span> <span style="color:#b8bfc6">MainWindow</span>()
            {
                <span style="color:#b8bfc6">InitializeComponent</span>();
            }
        }
    }</span>
2.1.3 安装 Prism 类库

Prism.Unity‌和‌Prism.DryIoc‌是Prism框架的两个依赖注入容器选项。它们的主要功能相似,但底层实现不同:

  • Prism.Unity‌:使用Unity容器,这是一个轻量级的、高性能的依赖注入容器,适用于需要高性能和灵活性的场景。Unity容器提供了丰富的功能和扩展性,适合需要高度定制的场景‌。

  • Prism.DryIoc‌:使用DryIoc容器,这是一个快速、轻量级的依赖注入容器,适用于需要快速启动和简单配置的场景。DryIoc以其简洁和高效著称,适合追求性能和简洁性的项目‌。

Prism.xxx 版本必须为兼容 .NetFramework 版本。

2.1.4 修改 App.xaml
  1. 删除StartupUri="Views/MainWindow.xaml"。

  2. 手动引入xmlns:prism="http://prismlibrary.com/"

<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">prism:PrismApplication</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_WpfApp1.App"</span>
             <span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
             <span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
             <span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_WpfApp1"</span>
             <span style="color:#7575e4">xmlns:prism</span>=<span style="color:#d26b6b">"http://prismlibrary.com/"</span><span style="color:#999977">></span>
    <span style="color:#999977"><</span><span style="color:#7df46a">Application.Resources</span><span style="color:#999977">></span>
         
    <span style="color:#999977"></</span><span style="color:#7df46a">Application.Resources</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">prism:PrismApplication</span><span style="color:#999977">></span></span></span>
2.1.5 修改 App.xaml.cs

1. 出现 CS0263:"App"的部分声明不能指定不同的基类,选中解决方案,右键重新生成解决方案。

2. 必须实现CreateShell 和 RegisterTypes 方法 

<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#c88fd0">namespace</span> <span style="color:#8d8df0">Prism_WpfApp1</span>
{
    <span style="color:#da924a">/// <summary></span>
    <span style="color:#da924a">/// App.xaml 的交互逻辑</span>
    <span style="color:#da924a">/// </summary></span>
    <span style="color:#c88fd0">public</span> <span style="color:#c88fd0">partial</span> <span style="color:#c88fd0">class</span> <span style="color:#8d8df0">App</span> : <span style="color:#b8bfc6">PrismApplication</span>
    {
        <span style="color:#c88fd0">protected</span> <span style="color:#c88fd0">override</span> <span style="color:#b8bfc6">Window</span> <span style="color:#b8bfc6">CreateShell</span>()
        {
            <span style="color:#da924a">//由 Prism 指定启动窗口</span>
            <span style="color:#c88fd0">return</span> <span style="color:#b8bfc6">Container</span>.<span style="color:#b8bfc6">Resolve</span><span style="color:#b8bfc6"><</span><span style="color:#b8bfc6">MainWindow</span><span style="color:#b8bfc6">></span>();
        }
​
        <span style="color:#da924a">//注册对象</span>
        <span style="color:#c88fd0">protected</span> <span style="color:#c88fd0">override</span> <span style="color:#c88fd0">void</span> <span style="color:#b8bfc6">RegisterTypes</span>(<span style="color:#b8bfc6">IContainerRegistry</span> <span style="color:#b8bfc6">containerRegistry</span>)
        {
            
        }
        
        <span style="color:#da924a">//手动指定 View 与 ViewModel关系</span>
        <span style="color:#da924a">/*protected override void ConfigureViewModelLocator()</span>
        <span style="color:#da924a">{</span>
            <span style="color:#da924a">base.ConfigureViewModelLocator();</span>
            <span style="color:#da924a">ViewModelLocationProvider.Register<视图名, 视图模型名>();</span>
        <span style="color:#da924a">}*/</span>
    }
}</span></span>

2.2 数据绑定及命令

2.2.1 MainWindow.xaml
<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">Window</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_WpfApp1.Views.MainWindow"</span>
        <span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
        <span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
        <span style="color:#7575e4">xmlns:d</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/expression/blend/2008"</span>
        <span style="color:#7575e4">xmlns:mc</span>=<span style="color:#d26b6b">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
        <span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_WpfApp1"</span>
        <span style="color:#7575e4">mc:Ignorable</span>=<span style="color:#d26b6b">"d"</span>
        <span style="color:#7575e4">Title</span>=<span style="color:#d26b6b">"MainWindow"</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"450"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"800"</span><span style="color:#999977">></span>
    <span style="color:#999977"><</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
        <span style="color:#999977"><</span><span style="color:#7df46a">StackPanel</span><span style="color:#999977">></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">TextBox</span> <span style="color:#7575e4">Text</span>=<span style="color:#d26b6b">"{Binding Name}"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"200"</span> <span style="color:#7575e4">Margin</span>=<span style="color:#d26b6b">"50"</span><span style="color:#999977">/></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">Button</span> <span style="color:#7575e4">Command</span>=<span style="color:#d26b6b">"{Binding BtnCommand}"</span> <span style="color:#7575e4">Content</span>=<span style="color:#d26b6b">"按钮"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"200"</span><span style="color:#999977">/></span>
        <span style="color:#999977"></</span><span style="color:#7df46a">StackPanel</span><span style="color:#999977">></span>
    <span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Window</span><span style="color:#999977">></span></span></span>
2.2.2 MainWindowViewModel
  1. BindableBase 实现了 INotifyPropertyChanged 接口,提供了Model数据变化通知UI更新的功能。

  2. DelegateCommand 实现了 ICommand等接口,实现了命令及拓展功能。

  3. 实现自动绑定ViewModeL,不需要手动将 ViewModel 绑定到 DataContext:

    1. 窗体|页面|用户控件必须放到Views目录下。

    2. 视图模型必须放到ViewModels目录下。

    3. 模型模型的名称,必须是窗体名称开头,且以ViewModel结尾。

    4. prism:ViewModelLocator.AutoWireViewModel="True",默认为true。

<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#c88fd0">namespace</span> <span style="color:#8d8df0">Prism_WpfApp1</span>.<span style="color:#b8bfc6">ViewModels</span>
{
    <span style="color:#c88fd0">public</span> <span style="color:#c88fd0">class</span> <span style="color:#8d8df0">MainWindowViewModel</span> : <span style="color:#b8bfc6">BindableBase</span>
    {
        <span style="color:#c88fd0">private</span> <span style="color:#1cc685">string</span> <span style="color:#b8bfc6">_name</span> <span style="color:#b8bfc6">=</span> <span style="color:#d26b6b">"zs"</span>;
​
        <span style="color:#c88fd0">public</span> <span style="color:#1cc685">string</span> <span style="color:#b8bfc6">Name</span>
        {
            <span style="color:#c88fd0">get</span> { <span style="color:#c88fd0">return</span> <span style="color:#b8bfc6">_name</span>; }
            <span style="color:#c88fd0">set</span>
            {
                <span style="color:#b8bfc6">_name</span> <span style="color:#b8bfc6">=</span> <span style="color:#c88fd0">value</span>;
                <span style="color:#b8bfc6">RaisePropertyChanged</span>();
            }
        }
​
        <span style="color:#c88fd0">public</span> <span style="color:#b8bfc6">ICommand</span> <span style="color:#b8bfc6">BtnCommand</span> { <span style="color:#c88fd0">get</span>; <span style="color:#c88fd0">set</span>; }
​
        <span style="color:#c88fd0">public</span> <span style="color:#b8bfc6">MainWindowViewModel</span>()
        {
            <span style="color:#b8bfc6">BtnCommand</span> <span style="color:#b8bfc6">=</span> <span style="color:#c88fd0">new</span> <span style="color:#b8bfc6">DelegateCommand</span>(<span style="color:#b8bfc6">GetValue</span>);
        }
​
        <span style="color:#c88fd0">public</span> <span style="color:#c88fd0">void</span> <span style="color:#b8bfc6">GetValue</span>()
        {
            <span style="color:#b8bfc6">MessageBox</span>.<span style="color:#b8bfc6">Show</span>(<span style="color:#b8bfc6">Name</span>);
            <span style="color:#b8bfc6">Name</span> <span style="color:#b8bfc6">=</span> <span style="color:#d26b6b">"ww"</span>;
        }
    }
}</span></span>

2.3 使用 Prsim 模版构建项目

2.3.1 管理拓展

2.3.2 添加拓展(Prism 模版)

2.3.3 先关闭 VS,再安装

07

2.3.4 创建 Prism 模版项目
  • 项目名不要以数字开头。

10

3. 区域(Region)

3.1 介绍

Prism框架中Region可以理解为一个UI容器,这些容器可以动态加载和卸载不同的视图和组件。

Region区域通常是一个控件,比如ContentControl、ItemsControl、TabControl。

可以理解为Region它就像是一个占位符,可以动态地向这个占位符中注入或者移除视图。

3.2 注册区域

示例代码中 Header 和 Content 使用region进行区域处理。

1. MainWindow.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">Window</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_BlankApp1.Views.MainWindow"</span>
        <span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
        <span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
        <span style="color:#7575e4">xmlns:prism</span>=<span style="color:#d26b6b">"http://prismlibrary.com/"</span>
        <span style="color:#7575e4">prism:ViewModelLocator.AutoWireViewModel</span>=<span style="color:#d26b6b">"True"</span>
        <span style="color:#7575e4">Title</span>=<span style="color:#d26b6b">"{Binding Title}"</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"350"</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"525"</span> <span style="color:#999977">></span>
    <span style="color:#999977"><</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
        <span style="color:#999977"><</span><span style="color:#7df46a">Grid.RowDefinitions</span><span style="color:#999977">></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">RowDefinition</span><span style="color:#999977">/></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">RowDefinition</span> <span style="color:#7575e4">Height</span>=<span style="color:#d26b6b">"5*"</span><span style="color:#999977">/></span>
        <span style="color:#999977"></</span><span style="color:#7df46a">Grid.RowDefinitions</span><span style="color:#999977">></span>
        <span style="color:#999977"><</span><span style="color:#7df46a">Grid.ColumnDefinitions</span><span style="color:#999977">></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">ColumnDefinition</span><span style="color:#999977">/></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">ColumnDefinition</span> <span style="color:#7575e4">Width</span>=<span style="color:#d26b6b">"3*"</span><span style="color:#999977">/></span>
        <span style="color:#999977"></</span><span style="color:#7df46a">Grid.ColumnDefinitions</span><span style="color:#999977">></span>
​
        <span style="color:#999977"><</span><span style="color:#7df46a">ContentControl</span> <span style="color:#7575e4">Grid.ColumnSpan</span>=<span style="color:#d26b6b">"2"</span> <span style="color:#7575e4">prism:RegionManager.RegionName</span>=<span style="color:#d26b6b">"HeaderRegion"</span><span style="color:#999977">/></span>
        
        <span style="color:#999977"><</span><span style="color:#7df46a">StackPanel</span> <span style="color:#7575e4">Grid.Row</span>=<span style="color:#d26b6b">"1"</span> <span style="color:#7575e4">Background</span>=<span style="color:#d26b6b">"Aquamarine"</span><span style="color:#999977">></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">Button</span> <span style="color:#7575e4">Content</span>=<span style="color:#d26b6b">"菜单1"</span><span style="color:#999977">/></span>
            <span style="color:#999977"><</span><span style="color:#7df46a">Button</span> <span style="color:#7575e4">Content</span>=<span style="color:#d26b6b">"菜单2"</span><span style="color:#999977">/></span>
        <span style="color:#999977"></</span><span style="color:#7df46a">StackPanel</span><span style="color:#999977">></span>
        
        <span style="color:#999977"><</span><span style="color:#7df46a">ContentControl</span> <span style="color:#7575e4">Grid.Row</span>=<span style="color:#d26b6b">"1"</span> <span style="color:#7575e4">Grid.Column</span>=<span style="color:#d26b6b">"1"</span> <span style="color:#7575e4">prism:RegionManager.RegionName</span>=<span style="color:#d26b6b">"ContentRegion"</span><span style="color:#999977">/></span>
    <span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">Window</span><span style="color:#999977">></span></span></span>

2. HeaderControl.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><span style="color:#999977"><</span><span style="color:#7df46a">UserControl</span> <span style="color:#7575e4">x:Class</span>=<span style="color:#d26b6b">"Prism_BlankApp1.Views.HeaderControl"</span>
             <span style="color:#7575e4">xmlns</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
             <span style="color:#7575e4">xmlns:x</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
             <span style="color:#7575e4">xmlns:mc</span>=<span style="color:#d26b6b">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span> 
             <span style="color:#7575e4">xmlns:d</span>=<span style="color:#d26b6b">"http://schemas.microsoft.com/expression/blend/2008"</span> 
             <span style="color:#7575e4">xmlns:local</span>=<span style="color:#d26b6b">"clr-namespace:Prism_BlankApp1.Views"</span>
             <span style="color:#7575e4">mc:Ignorable</span>=<span style="color:#d26b6b">"d"</span> 
             <span style="color:#7575e4">d:DesignHeight</span>=<span style="color:#d26b6b">"450"</span> <span style="color:#7575e4">d:DesignWidth</span>=<span style="color:#d26b6b">"800"</span><span style="color:#999977">></span>
    <span style="color:#999977"><</span><span style="color:#7df46a">Grid</span> <span style="color:#7575e4">Background</span>=<span style="color:#d26b6b">"AliceBlue"</span><span style="color:#999977">></span>
        <span style="color:#999977"><</span><span style="color:#7df46a">TextBlock</span> <span style="color:#7575e4">Text</span>=<span style="color:#d26b6b">"Header"</span> <span style="color:#7575e4">FontSize</span>=<span style="color:#d26b6b">"15"</span><span style="color:#999977">/></span>
    <span style="color:#999977"></</span><span style="color:#7df46a">Grid</span><span style="color:#999977">></span>
<span style="color:#999977"></</span><span style="color:#7df46a">UserControl</span><span style="color:#999977">></span></span></span>

3. ContentControl.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.ContentControlMain"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Prism_BlankApp1.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="DarkKhaki">
        <TextBlock Text="Content" FontSize="15"/>
    </Grid>
</UserControl></span></span>

4. App.xaml.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1
{
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册region控件
            containerRegistry.Register<HeaderControl>();
            containerRegistry.Register<ContentControl>();
        }
    }
}</span></span>

5. MainWindowViewModel.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private IRegionManager _regionManager;
        //MainWindowViewModel被创建时,会自动将 regionManager 传入
        public MainWindowViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            //将视图注册到对应的region中
            _regionManager.RegisterViewWithRegion("HeaderRegion", nameof(HeaderControl));
			_regionManager.RegisterViewWithRegion("ContentRegion", nameof(ContentControl));
            RegisterViewForRegion();
        }
    }</span></span>

4. 导航(Navigation)

4.1 介绍

可以实现应用程序中页面之间的导航和传递参数,简化应用程序的开发和维护‌。

4.2 注册导航

1. MenuControl.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><Window x:Class="Prism_BlankApp1.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525" >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="5*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>

        <ContentControl Grid.ColumnSpan="2" prism:RegionManager.RegionName="HeaderRegion"/>
        
        <StackPanel Grid.Row="1" Background="Aquamarine">
            <Button Content="菜单1" Command="{Binding NavigateCommand}" CommandParameter="UserControl1"/>
            <Button Content="菜单2" Command="{Binding NavigateCommand}" CommandParameter="UserControl2"/>
        </StackPanel>
        
        <ContentControl Grid.Row="1" Grid.Column="1" prism:RegionManager.RegionName="ContentRegion"/>
    </Grid>
</Window></span></span>

2. UserControl1.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BlankApp1.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <StackPanel Background="Azure">
        <TextBlock Text="页面1"/>
    </StackPanel>
</UserControl></span></span>

3. UserControl2.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.UserControl2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BlankApp1.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="Bisque">
        <TextBlock Text="页面2"/>
    </Grid>
</UserControl></span></span>

4. App.xaml.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册region控件
            containerRegistry.Register<HeaderControl>();
            containerRegistry.Register<ContentControlMain>();

            //注册导航控件
            containerRegistry.RegisterForNavigation<UserControl1>();
            containerRegistry.RegisterForNavigation<UserControl2>();
        }
    }
}</span></span>

5. MainWindowViewModel.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public DelegateCommand<string> NavigateCommand { get; set; }
        private IRegionManager _regionManager;

        public MainWindowViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            //将视图注册到对应的region中
            _regionManager.RegisterViewWithRegion("HeaderRegion", nameof(HeaderControl));
			_regionManager.RegisterViewWithRegion("ContentRegion", nameof(ContentControl));
            NavigateCommand = new DelegateCommand<string>(Navigate);
        }

        private void Navigate(string pageName)
        {
            _regionManager.RequestNavigate("ContentRegion", pageName);
        }
    }
}</span></span>

4.3 传递参数

1. MenuControlViewModel.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
    public class MenuControlViewModel
    {
        public DelegateCommand<string> NavigateCommand { get; set; }
        private IRegionManager _regionManager;
        
        public MenuControlViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            NavigateCommand = new DelegateCommand<string>(Navigate);

        }
        
        private void Navigate(string pageName)
        {
            NavigationParameters pairs = new NavigationParameters();
			pairs.Add("msg", "数据");
            _regionManager.RequestNavigate("ContentRegion", pageName, pairs);
        }
    }
}</span></span>

2. UserControl1ViewModel.cs

导航的目标视图需要通过实现INavigationAware接口来实现,一般在目标视图的视图模型继承自INavigaionAware接口来实现其对应的方法。

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
    public class UserControl1ViewModel : BindableBase, INavigationAware
    {
        private string _msg;

        public string Msg
        {
            get { return _msg; }
            set { SetProperty(ref _msg, value); }
        }

        private IRegionManager _regionManager;
        public UserControl1ViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
        }

        public bool IsNavigationTarget(NavigationContext navigationContext) => true;

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            NavigationParameters parameters = navigationContext.Parameters;
            Msg = parameters["msg"].ToString();
        }
    }
}</span></span>

3. UserControl1.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="Prism_BlankApp1.Views.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BlankApp1.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <StackPanel Background="Azure">
        <TextBlock Text="页面1"/>
        <TextBlock Text="{Binding Msg}"/>
    </StackPanel>
</UserControl></span></span>

4.4 导航日志

Prism的导航日志INavigationJournal的管理是自动运行的,其中包括记录成功的导航日志。而NavigationCallback是用来检测导航结果检查的,可以在这里根据导航成功或者失败做一些特殊处理。

1. MainWindow.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><Window x:Class="Prism_BlankApp1.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525" >
    <Window.Resources>
        <Style TargetType="TabItem">
            <Setter Property="Header" Value="{Binding DataContext.Head}"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="5*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>

        <ContentControl Grid.ColumnSpan="2" prism:RegionManager.RegionName="HeaderRegion"/>

        <StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
            <Button Content="后退" Command="{Binding HistoryCommand}" CommandParameter="back"/>
            <Button Content="前进" Command="{Binding HistoryCommand}" CommandParameter="next"/>
        </StackPanel>
        <StackPanel Grid.RowSpan="2" Grid.Row="1" Background="Aquamarine">
            <Button Content="菜单1" Command="{Binding NavigateCommand}" CommandParameter="UserControl1"/>
            <Button Content="菜单2" Command="{Binding NavigateCommand}" CommandParameter="UserControl2"/>
        </StackPanel>
        
        <ContentControl Grid.Row="2" Grid.Column="1" prism:RegionManager.RegionName="ContentRegion"/>
    </Grid>
</Window></span></span>

2. MenuControlViewModel.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Prism_BlankApp1.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public DelegateCommand<string> NavigateCommand { get; set; }
        public DelegateCommand<string> HistoryCommand { get; set; }
        private IRegionManager _regionManager;
        private IRegionNavigationJournal _journal;

        public MainWindowViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            _regionManager.RegisterViewWithRegion("HeaderRegion", nameof(HeaderControl));
            _regionManager.RegisterViewWithRegion("ContentRegion", nameof(ContentControl));
            NavigateCommand = new DelegateCommand<string>(Navigate);
            HistoryCommand = new DelegateCommand<string>(History);
        }

        private void Navigate(string pageName)
        {
            NavigationParameters pairs = new NavigationParameters();
            pairs.Add("msg", "数据");
            _regionManager.RequestNavigate("ContentRegion", pageName, NavigateComplete, pairs);
        }

        private void NavigateComplete(NavigationResult navigationResult)
        {
            if (navigationResult.Result == true)
            {
                _journal = navigationResult.Context.NavigationService.Journal;
            }
        }
        public void History(string msg)
        {
            if (_journal != null)
            {
                switch (msg)
                {
                    case "back":
                        if (_journal.CanGoBack)
                        {
                            _journal.GoBack();
                        }
                        break;
                    case "next":
                        if (_journal.CanGoForward)
                        {
                            _journal.GoForward();
                        }
                        break;
                }
            }
        }
    }
}</span></span>

5. 事件聚合器(EventAggregato)

5.1 介绍

事件聚合器是一种实现组件间松耦合通信的模式,不需要知道事件的发布者和订阅者是谁,从而减少组件间的依赖关系‌。

事件聚合器是一个设计模式,允许多个对象或组件通过中心化的事件管理系统进行通信,这个中心化的系统被称为事件聚合器‌。

5.2 通信

1. UserControl1.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="BlankApp1.Views.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BlankApp1.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <StackPanel Background="Bisque">
        <TextBlock Text="UserControl1"/>
        <Button Content="修改数据" Width="200" Command="{Binding UpdateDataCommand}"/>
    </StackPanel>
</UserControl></span></span>

2. UserControl1ViewModel.xaml.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace BlankApp1.ViewModels
{
    public class UserControl1ViewModel
    {
        public class MyEvent : PubSubEvent<string> { }
        public DelegateCommand UpdateDataCommand { get; set; }
        
        private IRegionManager _regionManager;
        private IEventAggregator _eventAggregator;
        
        public UserControl1ViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            _regionManager = regionManager;
            _eventAggregator = eventAggregator;
            UpdateDataCommand = new DelegateCommand(ToUpdate);
        }

        private void ToUpdate()
        {
            _regionManager.RequestNavigate("ContentRegion", nameof(UserControl2));
            _eventAggregator.GetEvent<MyEvent>().Publish("要修改的数据");
        }
    }
}</span></span>

3. UserControl2.xaml

<span style="background-color:#333333"><span style="color:#b8bfc6"><UserControl x:Class="BlankApp1.Views.UserControl2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BlankApp1.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="Pink">
        <TextBlock Text="{Binding Data}" FontSize="15"/>
    </Grid>
</UserControl></span></span>

4. UserControl2ViewModel.xaml.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">{
    public class UserControl2ViewModel:BindableBase
    {
        private string _data;

        public string Data
        {
            get { return _data; }
            set { SetProperty(ref _data, value); }
        }

        public UserControl2ViewModel(IEventAggregator eventAggregator)
        {
            eventAggregator.GetEvent<MyEvent>().Subscribe(GetValue);
        }

        private void GetValue(string data)
        {
            Data = data;
        }
    }
}</span></span>

6. 模块化(Module)

5.1 介绍

Prism框架支持将应用程序拆分为多个模块,每个模块具有自己的视图和视图模型。这种模块化的设计使得应用程序更加灵活和可扩展。

5.2 演示

1. 创建 Prism 模块项目

2. 项目结构

3. Module1Module.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace Module1
{
    public class Module1Module: IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            //注册非导航控件
            var regionManager = containerProvider.Resolve<RegionManager>();
            regionManager.RegisterViewWithRegion("ContentRegion", typeof(ContentControl));
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册导航控件
            containerRegistry.RegisterForNavigation<UserControl1>();
            containerRegistry.RegisterForNavigation<UserControl2>();
            containerRegistry.RegisterForNavigation<UserControl3>();
        }
    }
}</span></span>

4. App.xaml.cs

<span style="background-color:#333333"><span style="color:#b8bfc6">namespace BlankApp1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.Register<HeaderControl>();
            //containerRegistry.Register<ContentControl>();

            //containerRegistry.RegisterForNavigation<UserControl1>();
            //containerRegistry.RegisterForNavigation<UserControl2>();
            //containerRegistry.RegisterForNavigation<UserControl3>();
        }

        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {
            base.ConfigureModuleCatalog(moduleCatalog);
            moduleCatalog.AddModule<Module1Module>();
        }
    }
}</span></span>

5.3 区域和模块化总结

  1. 区域:将一个view中的内容拆分到不同的view当中。

  2. 模块化:将一个项目中的 Models Views ViewModels 拆分到不同的模块中。

一款轻量而功能强大的点云可视化和编辑软件,支持pcd, ply, las等多种格式,轻松打开海量点云数据,支持多方式多字段渲染点云,对点进行方便的查询、量测和编辑,提供了地面滤波算法,可应用于测绘、高精地图、SLAM等领域。 PCDViewer是一款专业的点云数据处理软件,特别适用于处理和编辑大规模点云数据。该软件支持多种点云文件格式,包括pcd、ply和las等,这些格式广泛应用于激光雷达扫描数据、三维建模以及其他测绘技术。PCDViewer的强大之处在于其轻量级的系统要求与丰富的功能集,使得用户可以在Windows、Ubuntu等操作系统上轻松运行软件,高效地处理海量点云数据。 这款软件的一个主要特点是其多方式多字段渲染点云的能力。这允许用户根据不同的属性,如颜色、强度、高度等,对点云进行视觉上的分类和区分,从而更直观地分析和理解点云数据。此外,PCDViewer还提供了方便的查询、量测和编辑功能,允许用户直接对点云数据进行操作,诸如添加注释、删除噪声点或进行精确测量等,极大地提高了工作效率。 软件还内置了地面滤波算法,这一功能对于测绘学、地理信息系统(GIS)以及机器人导航和定位(SLAM)等领域尤为关键。地面滤波算法能够从点云数据中分离出地面点和非地面点,这对于如道路建模、地形分析、植被测量等应用来说至关重要。通过分离地面点,可以更准确地进行地面建模和地形特征分析,为自动化系统提供清晰的环境地图。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值