WPF -- 初识Prism框架

目录

一、安装&新建项目 

二、View与ViewModel的绑定

三、属性通知

四、命令

五、Region(区域)

六、Navigation(导航)

七、Dialog(对话框)

八、Module(模块)


一、安装&新建项目 

      1. Nuget安装prism.core,prism.wpf,prism.unity

      2.可安装vs扩展包快速创建项目:Prism Template Pack

         扩展 --> 管理扩展 -->联机,搜索Prism Template Pack,下载完成后重启VS安装,

    tips: vs2019下载扩展时,会出现下载失败的情况,可用电脑连接手机热点下载

      3.新建项目,选择Prism Blank App(.NET Core),容器有两种(Unity,Dryloc),本文用Unity容器,

    App.xaml

public partial class App
    {
        //重写CreateShell方法,在App.xaml文件中,不再设置StartupUri
        protected override Window CreateShell()
        {
            //使用容器创建主窗体
            return Container.Resolve<MainWindow>();
        }

        //给容器中注册对象
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {

        }
    }

 二、View与ViewModel的绑定

  1. View中引入名称空间:xmlns:prism="http://prismlibrary.com/"
  2. 设置为自动关联:prism:ViewModelLocator.AutoWireViewModel="True"

tips: 1. 必须是Views和ViewModels目录

        2. 需要保证命名规范的正确性

              ① View可以以View结尾,也可以不写

              ② ViewModel必须以View的名称+”ViewModel”进行命名

         3. eg:   Views: Main, HomeView;

                     ViewModel:MainViewModel, HomeViewModel

    3. 默认的查找逻辑的源码

var viewName = viewType.FullName;
viewName = viewName.Replace(".Views.", ".ViewModels.");
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
var suffix = viewName.EndsWith("View") ? "Model" : "ViewModel";
var viewModelName = String.Format(CultureInfo.InvariantCulture, "{0}{1}, {2}", viewName, suffix, viewAssemblyName);
return Type.GetType(viewModelName);

三、属性通知

     1. ViewModel继承BindableBase抽象类,实现INotifyPropertyChanged接口,使用SetProperty

public class MainWindowViewModel : BindableBase
    {
        private string _title;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        
    }

四、命令

    1. 添加引用  using Prism.Commands;

    2. 使用DelegateCommand类,实现了ICommand接口,eg

public class RegionAViewModel:BindableBase
    {
        //该属性控制按钮是否可用
        private bool _isEnable = true;
        public bool IsEnable
        {
            get { return _isEnable; }
            set { SetProperty<bool>( ref _isEnable, value); }
        }
        public DelegateCommand ShowCommand { get; private set; }
        public DelegateCommand StartCommand { get; private set; }
        public DelegateCommand<string> CannelCommand { get; private set; }

        public RegionAViewModel() 
        {
            //命令绑定到方法Show()
            ShowCommand = new DelegateCommand(Show);
            //调用了ObservesCanExecute方法,这个方法有一个Fun委托参数用来表示该命令是否可以执行(表现在界面上就是按钮灰调),
            StartCommand = new DelegateCommand(Start).ObservesCanExecute(() => IsEnable);
            //带string参数     这里直接写true,表示按钮一直可用
            CannelCommand = new DelegateCommand<string>(Cannel).ObservesCanExecute(() => true);
        }

        private void Show() { }
        private void Start(){ }
        private void Cannel(string str)  { }
    }

 五、Region(区域)

       1. 概念:在Prism当中,一个页面我们可以不再为其固定显示的内容,而这种概念变成了区域  (Region)划分的概念。将页面显示的区域划分成N个Region,每一个Region将动态分配区域。      它将负责承担我们的UI组件或者控件。

      2. 注册使用,eg

         在MainWindow.xaml.cs中,绑定region与view

public partial class MainWindow : Window
    {
        //因为MainWindow对象是我们在App类中使用容器解析得到的,那么它需要的依赖IRegion也会自动被创建
        //通过构造函数传入IRegionManager参数
        public MainWindow(IRegionManager regionManager, IContainerExtension container )
        {
            InitializeComponent();
            //绑定region和view   参1:region的名字   参2:region要加载的view
            regionManager.RegisterViewWithRegion("RegionA", typeof(RegionAView));
            regionManager.RegisterViewWithRegion("RegionB",typeof(RegionBView));
        }
    }

        在MainWindow.xaml中声明,RegionName即为之前注册的名字,这样定义的RegionA区域显示的就是RegionAView的内容

<ContentControl Grid.Row="0" prism:RegionManager.RegionName="RegionA"/>

六、Navigation(导航)

      1. Prism用Navigation功能来进行页面切换、导航, 将View注册到导航中

      2. 将View注册到导航中,App.xaml.cs

protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //View对象注册为单例对象
            containerRegistry.RegisterSingleton<RegionAView>();

            //注册导航页面,其中第一个参数是View的类型,第二个参数是ViewName(可省略,则默认为View类型的类名)
            containerRegistry.RegisterForNavigation(typeof(RegionAView),"ViewA");

        }

      3. 添加按钮触发导航

<!--为Navigation注册的Region-->
<ContentControl Grid.Row="3" prism:RegionManager.RegionName="Navigation"/>            
<Button Content="导航"  Width="100" Command="{Binding NavigationCommand}"  CommandParameter="ViewA"/>

      4. 绑定命令,请求导航

public class MainWindowViewModel : BindableBase
    {
        public DelegateCommand<string> NavigationCommand { get; private set; }
        private IRegionManager RegionManager;
        public MainWindowViewModel(IRegionManager regionManager)
        {
            RegionManager = regionManager;
            NavigationCommand = new DelegateCommand<string>(Navigation);
        }

        private void Navigation(string page)
        {
            //请求导航时的携带的参数
            NavigationParameters parameters = new NavigationParameters();
            parameters.Add("param", "参数");
            //请求导航,即region显示之前注册的view
            //参数1:RegionName,:参数2:我们前面注册的ViewName,参数3:请求导航完成的回调函数,参数4:请求导航时的参数
            RegionManager.RequestNavigate("Navigation", page, NavigationCallback, parameters);
        }

        private void NavigationCallback(NavigationResult result)
        {
            Debug.WriteLine("回调");
            Debug.WriteLine(result.Context.Uri);
            Debug.WriteLine(result.Result.Value);
        }
}

七、Dialog(对话框)

        1. Prism提供了一组对话服务,封装了常用的对话框组件的功能,使View用show/showdialog弹出

        2. 注册Dialog,App.xaml.cs

protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //注册Dialog, <DialogView>:使用的view       "DialogViewName":起的DialogName
            containerRegistry.RegisterDialog<DialogView>("DialogViewName");
        }

        3. 添加按钮

<Button Content="Dialog"  Width="100" Command="{Binding DialogCommand}"/>

        4. 绑定命令,触发dialog

public class MainWindowViewModel : BindableBase
    {
        public DelegateCommand DialogCommand { get; private set; }
        private IDialogService DialogService;
        public MainWindowViewModel(IRegionManager regionManager, IDialogService dialogService)
        {
            DialogService = dialogService;
            DialogCommand = new DelegateCommand(DialogShow);
        }

        private void DialogShow()
        {
            IDialogParameters parameters = new DialogParameters();
            parameters.Add("param", "dialog携带参数");
            //打开对话框,参数1:之前注册的DialogName, 参数2:传递给对话框的参数, 参数3:对话框被关闭时的回调函数
            DialogService.ShowDialog("DialogViewName", parameters, DialogCallback);
        }

        private void DialogCallback(IDialogResult result)
        {
            //获取对话框的结果
            ButtonResult btnResult = result.Result;
            Debug.WriteLine(btnResult.ToString());
            //对话框关闭时传的参数
            string str = result.Parameters.GetValue<string>("param");
            Debug.WriteLine(str);  
        }

    }

        5. 使用对话框的view相对应的viewmodel实现接口IDialogAware,来监控对话框

public class DialogViewModel : BindableBase,IDialogAware
    {
        private string _param;

        public string Param
        {
            get { return _param; }
            set { SetProperty(ref _param, value); }
        }

        //Yes按钮
        public DelegateCommand YesCommand { get; private set; }
        //No按钮
        public DelegateCommand NoCommand { get; private set; }
        public DialogViewModel()
        {
            Param = "Hello DialogView";
            YesCommand = new DelegateCommand(YesDo);
            NoCommand = new DelegateCommand(NoDo);
        }

        private void YesDo() 
        {
            IDialogParameters parameters = new DialogParameters();
            parameters.Add("param", "dialog点击yes关闭携带的参数");
            //点击Yes按钮的时候关闭对话框,并且传递对话框结果(结果中还可以带参数)
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
        }
        private void NoDo()
        {
            RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
        }

        #region IDialogAware所属方法
        //表示对话框窗体的标题。(打开对话框的时候,其实还是将该用户控件装载到了一个窗体中)
        public string Title => "DialogTest";
        //触发这个事件去关闭对话框,这个事件的订阅就是在ShowDialog时声明的当对话框关闭后的回调函数。
        public event Action<IDialogResult> RequestClose;
        //如果返回true,则表示可以关闭对话框,否则不可以关闭对话框。(这时按钮不会变灰,但是点击无效。即使触发RequestClose也会无效)
        public bool CanCloseDialog()
        {
            return true;
        }
        //当对话框被关闭的时候触发这个方法(无论是点击关闭按钮还是触发事件)
        public void OnDialogClosed()
        {
            Debug.WriteLine($"对话框被关闭,调用{MethodBase.GetCurrentMethod().Name}");
        }
        //当对话框被打开的时候触发这个方法,并且传递对话框参数进来
        public void OnDialogOpened(IDialogParameters parameters)
        {
            Param = parameters.GetValue<string>("param");

        }
        #endregion

    }

八、Module(模块)

        1. prism项目在一个启动页当中划分好对应的区域。将不同的功能放到不同的module中,此时可以灵活的配置应用程序的功能,可以动态的加载应用程序模块,为指定的Region动态分配内容,即一个解决方案下有多个独立功能的module

        2. 创建module

        3. 如下图,主项目为PrismTest,又添加了两个独立的module:ModuleA、ModuleB

         4. 在ModuleAModule.cs中注册对象,实现了IModule接口

public class ModuleAModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            //绑定View与Region的映射关系    即名称为ModuleA的region区域将显示ViewA
            var regionManager = containerProvider.Resolve<IRegionManager>();
            regionManager.RegisterViewWithRegion("ModuleA",typeof(ViewA));
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //也可以将module的view注册为导航   可以通过导航实现多个Module间的切换
            containerRegistry.RegisterForNavigation(typeof(ViewA),"ViewA");
        }
    }

         5. 添加模块,App.xaml.cs

//先添加对ModuleA项目的引用,然后重写添加模块函数。
        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {
            base.ConfigureModuleCatalog(moduleCatalog);
            //添加自定义模块  ModuleAModule: 这个是module模块实现了IModule的类
            moduleCatalog.AddModule<ModuleAModule>();
        }

参考:

[1] https://github.com/PrismLibrary/Prism

[2] WPF Prism(五)Navigation_目标:MVP-CSDN博客

[3] [Windows] Prism 8.0 入门(下):Prism.Wpf 和 Prism.Unity - 云+社区 - 腾讯云 (tencent.com)

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值