zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Prim WPF入门-选项卡式导航实现

WPF入门 实现 导航 选项卡 prim
2023-09-14 09:16:29 时间

Prism

Prism是一个用于在 WPF、Xamarin Form、Uno 平台和 WinUI 中构建松散耦合、可维护和可测试的 XAML 应用程序框架。

VS Prism插件

  • Prism Template Pack
    用于快速创建基于Prism的项目

项目创建

在这里插入图片描述
在这里插入图片描述

创建好了之后项目很简单,与普通的WPF项目包含的源文件数量一致。

实现选项卡式导航

  • 添加 → 新建项 → 选择 “Prism UseControl(WPF)”
    在这里插入图片描述
    插件会自动创建出对应 View 的 ViewModel

基类实现

  • 封装 ViewModelBase 用于实现导航所需要的方法
using Prism.Mvvm;
using Prism.Regions;

namespace PrismTabNavigation.ViewModels
{
    public class ViewModelBase : BindableBase, INavigationAware
    {
        private string _title = string.Empty;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true; // 返回true:导航到目标;返回false:new子页面
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {

        }
    }
}

Prism中ViewModel 必须继承 BindableBase 类,这里的 ViewModelBase 用于实现 BindableBase 不具备的能力,后面的子页面都将继承 ViewModelBase 类,实现导航及公共属性、方法。

  • 新建两个 View,只需要在ViewModel中为Title属性赋值即可

在这里插入图片描述

在 MainWindowViewModel 中实现相关命令、在 MainWindow.xaml 中实现布局

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;

namespace PrismTabNavigation.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        IRegionManager _region;

        private string _title = "Prism Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public MainWindowViewModel(IRegionManager region)
        {
            _region = region;
        }


        private DelegateCommand<string> _GoCommand;
        public DelegateCommand<string> GoCommand => _GoCommand ??= new DelegateCommand<string>(ExecuteGoCommand);

        void ExecuteGoCommand(string uri)
        {
            _region.RequestNavigate("ContentRegion", uri);
        }

        private DelegateCommand<object> _DeleteCommand;
        public DelegateCommand<object> DeleteCommand => _DeleteCommand ??= new DelegateCommand<object>(Execute_DeleteCommand);

        void Execute_DeleteCommand(object obj)
        {
            _region.Regions["ContentRegion"].Remove(obj);
        }
    }
}
<Window
    x:Class="PrismTabNavigation.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:PrismTabNavigation.Views"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="800"
    Height="450"
    prism:ViewModelLocator.AutoWireViewModel="True"
    WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <StackPanel>
            <Button
                Command="{Binding GoCommand}"
                CommandParameter="TabOne"
                Content="选项1" />
            <Button
                Command="{Binding GoCommand}"
                CommandParameter="TabTwo"
                Content="选项2" />
        </StackPanel>
        <TabControl Grid.Column="1" prism:RegionManager.RegionName="ContentRegion">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=Content.DataContext.Title}" />
                        <Button
                            Width="20"
                            Height="20"
                            Command="{Binding RelativeSource={RelativeSource AncestorType=local:MainWindow}, Path=DataContext.DeleteCommand}"
                            CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=Content}"
                            Content="×" />
                    </StackPanel>
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>
    </Grid>
</Window>

命令绑定不再做说明,不会可以去看 Microsoft 文档

注意:现在还不能实现完整的导航

注入视图

  • 在 App.xaml.cs 文件中的 RegisterTypes 方法中 注入相关视图
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterForNavigation<TabOne>(nameof(TabOne));
    containerRegistry.RegisterForNavigation<TabTwo>(nameof(TabTwo));
}

效果预览

在这里插入图片描述