Wpf 使用 Prism 实战开发Day04

一.菜单导航实现

Wpf 使用 Prism 实战开发Day04_第1张图片


1.首先创建出所有的页面(View)及对应的页面逻辑处理类(ViewModel)

  1.  IndexView(首页)-----------------IndexViewModel
  2. ToDoView(待办事项)------------ToDoViewModel
  3. MemoView(忘备录)--------------MemoViewModel
  4. SettingsView(设置)--------------SettingsViewModel

注意:创建View时,添加的是用户控件 

Wpf 使用 Prism 实战开发Day04_第2张图片

2. 在 MainView.xaml 添加内容展示区域 

通俗点理解就是,其他页面的内容需要有控件去展现出来给用户看。然后就用到一个ContentControl  控件来展现内容,并且也需要用到 Prism 框架里面的区域 (并且通过定义一个区域名称来定位到展现的位置)。我是这样理解的。首先这不是教程,是我学习的记录,如果错了,就错了。

  • 例如,在 ContentControl 中定义一个区域名称,并且使用 prism 注册这个区域

 建议:通过一个扩展类来管理定义的一些属性名称

例如:当前定义的区域名称,通过建立一个扩展类来进行管理

Wpf 使用 Prism 实战开发Day04_第3张图片

 public static class PrismManager
 {
     public static readonly string MainViewRegionName = "MainViewReion";
 }

  • 扩展类定义完成后,需要在使用到的 MainView 页面中,添加命名空间进行使用这个静态扩展类
xmlns:ext="clr-namespace:MyToDo.Extensions"
  1. xmlns: 是引入命名空间固定的写法
  2. ext 是自定义的名称
  3. = 号后面是扩展类所在的命名空间 

  • 最后,在 ContentControl 控件中去引用这个静态类定义的属性
 

x:Static 是引用静态类型的属性的固定前缀的写法 


 3.进行页面导航注册

  • 在App.xaml.cs中,把页面(View)和 业务处理类(ViewModel) 进行依赖关联并注册进导航容器中

Wpf 使用 Prism 实战开发Day04_第4张图片

  /// 
  /// 依懒注入的方法
  /// 
  /// 
  protected override void RegisterTypes(IContainerRegistry containerRegistry)
  {
      containerRegistry.RegisterForNavigation();
      containerRegistry.RegisterForNavigation();
      containerRegistry.RegisterForNavigation();
      containerRegistry.RegisterForNavigation();
  }

 5. 接着在添加导航命令

  • 在MainViewModel.cs 中,添加导航命令。作用是用来驱动整个页面的导航
  • 接着,还需要添加 IRegionManager,通过在Prism 提供的IRegionManager.Regions 来找到应用程序所注册的导航区域名称(就是内容展现区域定义的名称)
  • 最后,通过.出来RequestNavigate 属性,取菜单传过来的命名空间做为导航的目标页面。
 public class MainViewModel: BindableBase
 {
     public MainViewModel(IRegionManager regionManager)
     {
         NavigateCommand = new DelegateCommand(Navigate);
         this.regionManager = regionManager;
     }

/// 
/// 导航方法
/// 
/// 菜单
private void Navigate(MenuBar bar)
{
    //命名空间为空,不进行导航
    if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;

    regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace);
}
      /// 
      /// 导航命令
      /// 
     public DelegateCommand NavigateCommand { get; private set; }

 }

6.实现上一步,下一步导航功能

通过添加导航日志 IRegionNavigationJournal 来实现,上一步,下一步的导航功能

  • 修改导航方法,添加导航成功回调函数
 /// 
 /// 导航方法
 /// 
 /// 菜单
 private void Navigate(MenuBar bar)
 {
     //命名空间为空,不进行导航
     if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;

     regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>
     {

     }); 
 }
  • 添加一个区域导航日志 IRegionNavigationJournal,用来记录导航的结果 ,并且在回调函数中实例化导航日志
 public class MainViewModel: BindableBase
 {
     public MainViewModel(IRegionManager regionManager)
     {
         NavigateCommand = new DelegateCommand(Navigate);
         this.regionManager = regionManager;
     }

     /// 
     /// 导航方法
     /// 
     /// 菜单
     private void Navigate(MenuBar bar)
     {
         //命名空间为空,不进行导航
         if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;

         regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>
         {
             journal=back.Context.NavigationService.Journal;      
         }); 
     }
          
     /// 
     /// 导航命令
     /// 
     public DelegateCommand NavigateCommand { get; private set; }

     private readonly IRegionManager regionManager;
     /// 
     /// 导航日志
     /// 
     private IRegionNavigationJournal journal;

 }
  • 接着,再添加两个命令,绑定前端按钮点击上一步或下一步按钮,并且进行初始化
 public class MainViewModel: BindableBase
 {
     public MainViewModel(IRegionManager regionManager)
     {
         NavigateCommand = new DelegateCommand(Navigate);
         this.regionManager = regionManager;
         GoBackCommand = new DelegateCommand(() =>
         {
             if(journal!=null && journal.CanGoBack) journal.GoBack();
         });
         GoForwardCommand = new DelegateCommand(() =>
         {
             if (journal != null && journal.CanGoForward) journal.GoForward();
         });
     }

     /// 
     /// 导航方法
     /// 
     /// 菜单
     private void Navigate(MenuBar bar)
     {
         //命名空间为空,不进行导航
         if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;

         regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>
         {
             journal=back.Context.NavigationService.Journal;      
         }); 
     }
          
     /// 
     /// 导航命令
     /// 
     public DelegateCommand NavigateCommand { get; private set; }

     /// 
     /// 下一步
     /// 
     public DelegateCommand GoBackCommand { get; private set; }
     /// 
     /// 上一步
     /// 
     public DelegateCommand GoForwardCommand { get; private set; }

     
     private readonly IRegionManager regionManager;
     /// 
     /// 导航日志
     /// 
     private IRegionNavigationJournal journal;
  
 }
  • 最后,在MainView页面的上一步和下一步按钮绑定ViewMode 写好的命令

Wpf 使用 Prism 实战开发Day04_第5张图片

7.在ListBox中,添加事件行为,作用是,当用户选中子项内容的时候,触发导航的行为。

  • 需要添加行为的命名空间

引入行为命名空间 xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

  •  接着在ListBox 中,添加选中行为事件,来触发导航

Wpf 使用 Prism 实战开发Day04_第6张图片


    
        
    
  •  Interaction.Triggers  行为触发器
  • EventTrigger 触发的事件
  • EventName 触发事件的名称,这个事件命名,一定是ListBox存在的事件名称,不是随便起的名称
  • InvokeCommandAction 绑定后台要触发的导航命令
  • CommandParameter 绑定当前选中项。例如。这是传过去后台命令的参数

例如,上面是通过选中ListBox Item的子项来触发导航命令

8.优化点击菜单子项的同时关闭左侧菜单

  • 只需要绑定ListBox 的SelectionChanged 选择事件,点击的时候让左侧边框收起即可

//菜单选择事件
menuBar.SelectionChanged += (s, e) =>
{
    drawerHost.IsLeftDrawerOpen = false;
};
  • menuBar  是ListBox 定义的名称
  • drawerHost 是左侧弹框定义的名称

二.源码 

  • MainView.xaml 


    

        
            
            
                
                 
                    
                    
                        
                            
                                
                            
                        
                        
                    
                    
                    
                    
                        
                            
                                
                            
                        
                        
                            
                                
                                    
                                    
                                
                            
                        
                    
                    
                    
                
            

            
                
                
                    
                        
                        
                            

                            
                            
                            
                        
                    

                

                
                
            
        
    

  •  MainView.xaml.cs

/// 
/// MainView.xaml 的交互逻辑
/// 
public partial class MainView : Window
{
    public MainView()
    {
        InitializeComponent();
        //最小化
        btnMin.Click += (s, e) =>
        {
            this.WindowState = WindowState.Minimized;//窗口设置最小
        };
        //最大化
        btnMax.Click += (s, e) =>
        {
            //判断窗口是否是最小化状态
            if (this.WindowState == WindowState.Maximized)
            {
                this.WindowState = WindowState.Normal; //改成正常状态
            }
            else
            {
                this.WindowState = WindowState.Maximized;//最大化
            }
        };
        //关闭
        btnClose.Click += (s, e) =>
        {
            this.Close();
        };
        //鼠标拖动事件
        ColorZone.MouseMove += (s, e) =>
        {
            //如果鼠标在拖动
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                this.DragMove();//让窗口移动
            }
        };

        //导航栏双击事件
        ColorZone.MouseDoubleClick += (s, e) =>
        {
            //双击时,如果是窗口是正常形态,就变成最大化
            if (this.WindowState == WindowState.Normal)
            {
                this.WindowState = WindowState.Maximized;
            }
            else
            {
                this.WindowState = WindowState.Normal;//否则就变成正常的形态
            }
        };
        //菜单选择事件
        menuBar.SelectionChanged += (s, e) =>
        {
            drawerHost.IsLeftDrawerOpen = false;
        };
    }
}
  • MainViewModel

public class MainViewModel: BindableBase
{
    public MainViewModel(IRegionManager regionManager)
    {
        MenuBars=new ObservableCollection();
        CreateMenuBar();
        NavigateCommand = new DelegateCommand(Navigate);
        this.regionManager = regionManager;
        GoBackCommand = new DelegateCommand(() =>
        {
            if(journal!=null && journal.CanGoBack) journal.GoBack();
        });
        GoForwardCommand = new DelegateCommand(() =>
        {
            if (journal != null && journal.CanGoForward) journal.GoForward();
        });
    }

    /// 
    /// 导航方法
    /// 
    /// 菜单
    private void Navigate(MenuBar bar)
    {
        //命名空间为空,不进行导航
        if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;

        regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>
        {
            journal=back.Context.NavigationService.Journal;      
        }); 
    }
         
    /// 
    /// 导航命令
    /// 
    public DelegateCommand NavigateCommand { get; private set; }

    /// 
    /// 下一步
    /// 
    public DelegateCommand GoBackCommand { get; private set; }
    /// 
    /// 上一步
    /// 
    public DelegateCommand GoForwardCommand { get; private set; }

    private ObservableCollection menuBars;
    private readonly IRegionManager regionManager;
    /// 
    /// 导航日志
    /// 
    private IRegionNavigationJournal journal;
    public ObservableCollection MenuBars
    {
        get { return menuBars; }
        set { menuBars = value; RaisePropertyChanged(); }
    }
    void CreateMenuBar()
    {
        MenuBars.Add(new MenuBar() { Icon="Home",Title="首页",NameSpace="IndexView"});
        MenuBars.Add(new MenuBar() { Icon = "NotebookCheckOutline", Title = "待办事项", NameSpace = "ToDoView" });
        MenuBars.Add(new MenuBar() { Icon = "NotebookPlusOutline", Title = "忘备录", NameSpace = "MemoView" });
        MenuBars.Add(new MenuBar() { Icon = "Cog", Title = "设置", NameSpace = "SettingsView" });
    }
}
  • App.xaml.cs
 public partial class App : PrismApplication
 {
     /// 
     /// 创建启动页面
     /// 
     /// 
     protected override Window CreateShell()
     {
        return Container.Resolve();
     }
     /// 
     /// 依懒注入的方法
     /// 
     /// 
     protected override void RegisterTypes(IContainerRegistry containerRegistry)
     {
         containerRegistry.RegisterForNavigation();
         containerRegistry.RegisterForNavigation();
         containerRegistry.RegisterForNavigation();
         containerRegistry.RegisterForNavigation();
     }
 }

你可能感兴趣的:(WPF入门,wpf)