Prim WPF入门-选项卡式导航实现
- Prism
- VS Prism插件
- 项目创建
- 实现选项卡式导航
- 基类实现
- 在 MainWindowViewModel 中实现相关命令、在 MainWindow.xaml 中实现布局
- 注入视图
- 效果预览
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));
}