首页 > 其他分享 >Prism导航

Prism导航

时间:2024-09-29 14:22:32浏览次数:7  
标签:DelegateCommand regionManager journal void Prism 导航 public navigationContext

注册导航页面

注册区域

使用p:RegionManager.RegionName注册页面区域

<Window x:Class="WpfApp1.NavigationWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:WpfApp1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:p="http://prismlibrary.com/"
        Title="NavigationWindow"
        Width="800"
        Height="450"
        mc:Ignorable="d">
    <DockPanel>
        <Grid Width="220" DockPanel.Dock="Left">
            <StackPanel>
                <Button Margin="0,3"
                        Command="{Binding OpenViewCommand}"
                        CommandParameter="ViewA"
                        Content="View A" />
                <Button Margin="0,3"
                        Command="{Binding OpenViewCommand}"
                        CommandParameter="ViewB"
                        Content="View B" />
                <Button Margin="0,3" Content="View C" />
            </StackPanel>
        </Grid>
        <Grid>
            <!--<ContentControl p:RegionManager.RegionName="ViewRegion"/>-->
            <TabControl p:RegionManager.RegionName="ViewRegion">
                <TabControl.ItemContainerStyle>
                    <Style TargetType="TabItem">
                        <!--  TabItem的绑定数据源是页面对象  -->
                        <!--  TabItem的DataContext=View对象  -->
                        <!--  View对象的DataContext=对应的ViewModel  -->
                        <Setter Property="Header" Value="{Binding DataContext.Title}" />
                    </Style>
                </TabControl.ItemContainerStyle>
            </TabControl>
        </Grid>
    </DockPanel>
</Window>
public class NavigationWindowVewModel
    {
        public ICommand OpenViewCommand { get; set; }

        // 区域管理,需要拿到RegionManager
        IRegionManager _regionManager;
        public NavigationWindowVewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;

            OpenViewCommand = new DelegateCommand<string>(DoOpenView);
        }

        private void DoOpenView(string viewName)
        {
            _regionManager.RegisterViewWithRegion("ViewRegion", viewName);
        }
    }
 public class Startup : PrismBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            return Container.Resolve<NavigationWindow>();
            //return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<ViewA>();
            containerRegistry.RegisterForNavigation<ViewB>();
        }
        protected override void ConfigureViewModelLocator()
        {
            base.ConfigureViewModelLocator();
 
            ViewModelLocationProvider.Register(typeof(NavigationWindow).ToString(), typeof(NavigationWindowVewModel));

        }
       
    }
<UserControl x:Class="WpfApp1.Views.ViewA"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:WpfApp1.Views"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             d:DesignHeight="450"
             d:DesignWidth="800"
             mc:Ignorable="d">
    <StackPanel>
        <TextBox FontSize="20" Foreground="Orange" Text="View A" />
        <TextBlock FontSize="20" Foreground="Red" Text="{Binding Title}" />
        <Button Command="{Binding CloseTabCommand}" Content="Close" />
    </StackPanel>
</UserControl>
<UserControl x:Class="WpfApp1.Views.ViewB"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:WpfApp1.Views"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             d:DesignHeight="450"
             d:DesignWidth="800"
             mc:Ignorable="d">
    <Grid>
        <TextBlock FontSize="20" Foreground="Green" Text="View B" />
    </Grid>
</UserControl>
 public class ViewAViewModel 
    {
        public string Title { get; set; } = "View A";
        public ICommand CloseTabCommand { get; set; }

        IRegionManager _regionManager;
        public ViewAViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            CloseTabCommand = new DelegateCommand(DoCloseTab);
        }
        private void DoCloseTab()
        {

        }
   
    }
 public class ViewBViewModel 
    {
        public string Title { get; set; } = "View B";
        public ICommand CloseTabCommand { get; set; }

        IRegionManager _regionManager;
        public ViewBViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            CloseTabCommand = new DelegateCommand(DoCloseTab);
        }
        private void DoCloseTab()
        {

        }
}

导航页面传参——INavigationAware接口

 public class ViewAViewModel : INavigationAware
    {
        public string Title { get; set; } = "View A";
        public ICommand CloseTabCommand { get; set; }

        IRegionManager _regionManager;
        public ViewAViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            CloseTabCommand = new DelegateCommand(DoCloseTab);
        }
        private void DoCloseTab()
        {

        }
        #region INavigationAware接口方法
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            // 是否允许重复导航进来
            // 主-》A-》B-》A (显示前对象)  返回True
            // 主-》A-》B-》A(新对象)     返回false
            return true;

            // 编辑页面,通过主页的子项点击,打开这个页面,
            // 子项有很多,可能同时打开多个子项进行编辑
        }
        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            // 从当前View导航出去的时候触发
            // 从某个页面跳转到另一个页面的时候,可以把这个信息带过去
            navigationContext.Parameters.Add("abcd", "Hello ViewA");
        }
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            // 打开当前View的时候触发
            string arg = navigationContext.Parameters.GetValue<string>("abcd");
        }
        #endregion
    }
 public class NavigationWindowVewModel
    {
        public ICommand OpenViewCommand { get; set; }

        // 区域管理,需要拿到RegionManager
        IRegionManager _regionManager;
        public NavigationWindowVewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;

            OpenViewCommand = new DelegateCommand<string>(DoOpenView);
        }

        private void DoOpenView(string viewName)
        {
            //_regionManager.RegisterViewWithRegion("ViewRegion", viewName);
            // 向某个View中传递特定参数,参数对接到View的ViewModel里
            if (viewName == "ViewA")
            {
                NavigationParameters parameters = new NavigationParameters();
                parameters.Add("abcd", "Hello");
                _regionManager.RequestNavigate("ViewRegion", viewName, parameters);
            }
            else if (viewName == "ViewB")
                _regionManager.RequestNavigate("ViewRegion", viewName);
        }
    }

自动销毁——IRegionMemberLifetime接口

页面的ViewModel继承IRegionMemberLifetime接口

接口中的KeepAlive参数默认为true:非激活状态,在Region中保留

public class ViewAViewModel : INavigationAware , IRegionMemberLifetime
    {
        public string Title { get; set; } = "View A";
        public ICommand CloseTabCommand { get; set; }

        IRegionManager _regionManager;
        public ViewAViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            CloseTabCommand = new DelegateCommand(DoCloseTab);
        }
        public bool KeepAlive => false;
        private void DoCloseTab()
        {

        }
        #region INavigationAware接口方法
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            // 是否允许重复导航进来
            // 主-》A-》B-》A (显示前对象)  返回True
            // 主-》A-》B-》A(新对象)     返回false
            return true;

            // 编辑页面,通过主页的子项点击,打开这个页面,
            // 子项有很多,可能同时打开多个子项进行编辑
        }
        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            // 从当前View导航出去的时候触发
            // 从某个页面跳转到另一个页面的时候,可以把这个信息带过去
            navigationContext.Parameters.Add("abcd", "Hello ViewA");
        }
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            // 打开当前View的时候触发
            string arg = navigationContext.Parameters.GetValue<string>("abcd");
        }
        #endregion
    }

 

页面离开前的事件——IConfirmNavigationRequest接口

页面ViewModel实现IConfirmNavigationRequest接口

public class ViewAViewModel : INavigationAware,IRegionMemberLifetime,IConfirmNavigationRequest
    {
        public string Title { get; set; } = "View A";
        public ICommand CloseTabCommand { get; set; }

        IRegionManager _regionManager;
        public ViewAViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
            CloseTabCommand = new DelegateCommand(DoCloseTab);
        }
        private void DoCloseTab()
        {

        }
        
        #region IRegionMemberLifetime接口方法
        // 用来控制当前页面非激活状态,是否在Region中保留
        public bool KeepAlive => true;

        #endregion

        #region INavigationAware接口方法
        
        #region INavigationAware接口方法
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            // 是否允许重复导航进来
            // 主-》A-》B-》A (显示前对象)  返回True
            // 主-》A-》B-》A(新对象)     返回false
            return true;

            // 编辑页面,通过主页的子项点击,打开这个页面,
            // 子项有很多,可能同时打开多个子项进行编辑
        }
        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            // 从当前View导航出去的时候触发
            // 从某个页面跳转到另一个页面的时候,可以把这个信息带过去
            navigationContext.Parameters.Add("abcd", "Hello ViewA");
        }
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            // 打开当前View的时候触发
            string arg = navigationContext.Parameters.GetValue<string>("abcd");
        }
        #endregion
        
        #region IConfirmNavigationRequest接口方法
        // 当从当前页面跳转到另一个页面时触发
        // OnNavigatedFrom调用前执行
        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
        {
            // 打开某个页面,
            if (MessageBox.Show("是否离开当前页面?", "导航提示", MessageBoxButton.YesNo) ==
                MessageBoxResult.Yes)
            {
                /// 继续打开
                /// 
                continuationCallback?.Invoke(true);
            }
            else
                // 不被导航
                continuationCallback?.Invoke(false);
        }
        #endregion
    }

导航日志

编写测试程序

public class Startup : PrismBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<PrismRegion.Journal.Views.MainView>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewA>();
        containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewB>();
        containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewC>();
    }
}
public partial class App : Application
{
    public App()
    {
        new Startup().Run();
    }
}
<Window x:Class="Zhaoxi.PrismRegion.Journal.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Zhaoxi.PrismRegion.Journal.Views"
        xmlns:p="http://prismlibrary.com/"
        mc:Ignorable="d"
        Title="MainView" Height="450" Width="800">
    <Grid>
        <Button Content="Load Views" Command="{Binding BtnLoadCommand}" 
                VerticalAlignment="Top"/>
        <ContentControl p:RegionManager.RegionName="MainRegion" Margin="0,30,0,0"/>
    </Grid>
</Window>
public class MainViewModel
{
    public DelegateCommand BtnLoadCommand { get; set; }
    public MainViewModel(IRegionManager regionManager)
    {
        BtnLoadCommand = new DelegateCommand(() =>
        {
            regionManager.RequestNavigate("MainRegion", "ViewA");
        });
    }
}
<UserControl x:Class="Zhaoxi.PrismRegion.Journal.Views.ViewA"
             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:Zhaoxi.PrismRegion.Journal.Views"
             mc:Ignorable="d" FontSize="20"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <StackPanel>
            <TextBlock Text="View A" Foreground="Orange" />
            <Button Content="向后" Command="{Binding GoBackCommand}"/>
            <Button Content="向前" Command="{Binding ForwordCommand}"/>
        </StackPanel>
    </Grid>
</UserControl>

页面的ViewModel继承INavigationAware接口

在OnNavigatedTo方法中取出navigationContext.NavigationService.Journal

journal.GoBack()提供导航回退

public class ViewAViewModel : INavigationAware
{
    public DelegateCommand GoBackCommand { get; set; }
    public DelegateCommand ForwordCommand { get; set; }

    IRegionNavigationJournal journal;
    public ViewAViewModel(IRegionManager regionManager)
    {
        GoBackCommand = new DelegateCommand(() =>
        {
            if (journal.CanGoBack)
            {
                journal.GoBack();
            }
        });
        ForwordCommand = new DelegateCommand(() =>
        {
            if (journal.CanGoForward)
            {
                journal.GoForward();
            }
            else
            {
                regionManager.RequestNavigate("MainRegion", "ViewB");
            }
        });
    }

    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        journal = navigationContext.NavigationService.Journal;
    }

    public bool IsNavigationTarget(NavigationContext navigationContext)
    {
        return true;
    }

    public void OnNavigatedFrom(NavigationContext navigationContext)
    {

    }
}

 参照ViewA写ViewB和ViewC

修改对应ViewModel的GoBackCommand与ForwordCommand

public ViewBViewModel(IRegionManager regionManager)
{
    GoBackCommand = new DelegateCommand(() =>
    {
        if (journal.CanGoBack)
        {
            journal.GoBack();
        }
    });
    ForwordCommand = new DelegateCommand(() =>
    {
        if (journal.CanGoForward)
        {
            journal.GoForward();
        }
        else
        {
            regionManager.RequestNavigate("MainRegion", "ViewC");
        }
    });
}
public ViewCViewModel(IRegionManager regionManager)
{
    GoBackCommand = new DelegateCommand(() =>
    {
        if (journal.CanGoBack)
        {
            journal.GoBack();
        }
    });
    ForwordCommand = new DelegateCommand(() =>
    {
        if (journal.CanGoForward)
        {
            journal.GoForward();
        }
    });
}

运行后实现导航的前进后退

取消导航——IJournalAware

在ViewB的ViewModel中继承IJournalAware接口,并在实现方法中返回false。

public class ViewBViewModel : INavigationAware, IJournalAware
{
    public DelegateCommand GoBackCommand { get; set; }
    public DelegateCommand ForwordCommand { get; set; }

    IRegionNavigationJournal journal;
    public ViewBViewModel(IRegionManager regionManager)
    {
        GoBackCommand = new DelegateCommand(() =>
        {
            if (journal.CanGoBack)
            {
                journal.GoBack();
            }
        });
        ForwordCommand = new DelegateCommand(() =>
        {
            if (journal.CanGoForward)
            {
                journal.GoForward();
            }
            else
            {
                regionManager.RequestNavigate("MainRegion", "ViewC");
            }
        });
    }




    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        journal = navigationContext.NavigationService.Journal;
    }

    public bool IsNavigationTarget(NavigationContext navigationContext)
    {
        return true;
    }

    public void OnNavigatedFrom(NavigationContext navigationContext)
    {

    }

    // IJournalAware的方法实现 
    public bool PersistInHistory()
    {
        return false;
    }
}

运行后,导航会取消ViewB的导航

来源:https://www.cnblogs.com/ZHIZRL/p/17883434.html

 

标签:DelegateCommand,regionManager,journal,void,Prism,导航,public,navigationContext
From: https://www.cnblogs.com/ywtssydm/p/18439509

相关文章

  • PbootCms导航菜单标签的这些小技巧你都知道吗?
    为了帮助新手更好地理解和使用PbootCMS模板中的标签,以下是一些常见问题及其解决方案。1.常用的导航标签<spanstyle="font-size:14px;">{pboot:nav}<ahref="[nav:link]">[nav:name]</a>{/pboot:nav}</span>控制参数*num=数量:非必填,用于控制输出的数量。*parent=......
  • 无人机之视觉导航算法篇
    一、图像采集与预处理图像采集:无人机通过其搭载的摄像头或其他视觉传感器实时采集周围环境的图像信息。图像预处理:对采集到的图像进行预处理,包括滤波、降噪、增强等操作,以提高图像的质量和清晰度,为后续的特征提取和匹配奠定基础。二、特征提取与匹配特征提取:从预处理后的图......
  • pbootcms模板导航设置外链时新窗口打开
    在PbootCMS中,如果你想在模板导航中设置外链并在新窗口中打开,可以通过条件判断来实现这一功能。具体步骤如下:实现步骤编写条件判断代码:使用 {pboot:if} 语句来判断外链是否为空。如果外链不为空,则添加 target="_blank" 属性。整合到导航链接中:将条件判断代码嵌......
  • 蓝牙定位导航系统深度解析:技术原理、实现步骤与实战应用
    随着物联网(IoT)技术的飞速发展,蓝牙低功耗(BLE)技术凭借其低功耗、高兼容性及短距离通信的优势,在各类定位系统中占据了重要地位。其中,蓝牙定位导航系统作为室内定位解决方案的佼佼者,正逐步改变着我们的生活方式。本文将深入探讨蓝牙定位导航系统的技术原理、关键技术、实现步骤,并通......
  • uniapp h5端地图导航功能
    <template> <viewclass="container"> <viewclass="content"> <map:scale="14":show-location="true":show-compass="true"class="map-content" :latitude="position.lati......
  • gps卫星转发器 导航信号转发器 北斗转发器
    在现代社会的工作中,我们都会使用到卫星信号。但存在一个现象,那就是卫星信号不能够穿透建筑物,生产车间、实验室等室内环境下的测试工作就会遇到困难。SYN2309型GNSS信号转发器是由西安同步电子科技有限公司精心设计、自行研发生产的一款增益可调的GNSS全频段卫星信号转发系统,主要功......
  • PbootCMS默认面包屑导航样式修改及自定义的设置方法
    在使用PBootCMS建站时,如果需要对系统默认的面包屑标签进行样式修改,可以通过调整相应的参数来实现。以下是具体的步骤和示例代码:修改面包屑标签的样式自定义分隔符修改首页文本添加首页图标添加分割图标示例代码假设你需要修改面包屑标签的分隔符、首页文本以及图标,可以按......
  • 智慧养老导航:开启便捷养老新篇章
    我国人口老龄化加剧,养老问题成为社会关注的焦点。如何让老年人度过一个幸福、安康的晚年,成为政府、企业和社会共同探讨的课题。在这样的背景下,智慧养老应运而生,为我国养老事业注入了新的活力。而智慧养老导航作为融合各类智慧养老产品的平台,为老年人提供了便捷、贴心的养老服务,开......
  • uniapp 常用高度状态栏,导航栏,tab栏,底部安全高度
    实际效果//入参是否转换为rpxgetPosConfig(toRpx=true){ constsystemInfo=uni.getSystemInfoSync(); //#ifdefMP constmenuButtonInfo=uni.getMenuButtonBoundingClientRect(); //#endif constposConfig={ statu......
  • 导航信号转发器 北斗转发器 gps信号放大转发器
    卫星信号不能够穿透建筑物,生产车间、实验室等室内环境,对相应环境下的测试工作造成困难。GNSS信号转发器可实现将卫星信号从室外转发到室内,广泛的应用在大型基站实验室、隧道、矿井、航空制造,航空维修等行业。SYN2309型GNSS信号转发器产品概述SYN2309型GNSS信号转发器是由西安同步电......