# 04 - 导航系统示例 演示如何使用 Sharp.Wpf 的导航服务实现多页面 WPF 应用,包括页面跳转、参数传递、前进/后退等功能。 ## 🎯 学习目标 - 使用 `INavigationService` 实现页面导航 - 理解导航历史栈(前进/后退) - 页面间参数传递 - 导航生命周期钩子(INavigationAware) - 弹出式导航并获取结果 ## 📦 使用的模块 - **Sharp.Wpf** - INavigationService, NavigationService ## 🚀 快速运行 ```bash cd examples/04-Navigation dotnet run ``` ## 📝 核心代码讲解 ### 1. MainViewModel.cs - 主导航容器 ```csharp using Wpf.Navigation; public class MainViewModel : ViewModelBase { private readonly INavigationService _navigationService; private ViewModelBase? _currentPage; public ViewModelBase? CurrentPage { get => _currentPage; set => SetProperty(ref _currentPage, value); } public bool CanGoBack => _navigationService.CanGoBack; public bool CanGoForward => _navigationService.CanGoForward; public ICommand NavigateToHomeCommand { get; } public ICommand NavigateToProductsCommand { get; } public ICommand NavigateToSettingsCommand { get; } public ICommand GoBackCommand { get; } public ICommand GoForwardCommand { get; } public MainViewModel(INavigationService navigationService) { _navigationService = navigationService; // 监听导航事件 _navigationService.Navigated += (s, vm) => { CurrentPage = vm; OnPropertyChanged(nameof(CanGoBack)); OnPropertyChanged(nameof(CanGoForward)); }; // 导航命令 NavigateToHomeCommand = new AsyncCommand(async (ct) => { await _navigationService.NavigateAsync(); }); NavigateToProductsCommand = new AsyncCommand(async (ct) => { await _navigationService.NavigateAsync(); }); NavigateToSettingsCommand = new AsyncCommand(async (ct) => { await _navigationService.NavigateAsync(); }); GoBackCommand = new AsyncCommand(async (ct) => { await _navigationService.GoBackAsync(); }, () => CanGoBack); GoForwardCommand = new AsyncCommand(async (ct) => { await _navigationService.GoForwardAsync(); }, () => CanGoForward); // 初始导航到首页 Task.Run(async () => await _navigationService.NavigateAsync()); } } ``` ### 2. ProductsViewModel.cs - 带参数的页面 ```csharp public class ProductsViewModel : ViewModelBase, INavigationAware { private readonly INavigationService _navigationService; private readonly IDialogService _dialogService; private string _category = "全部"; public string Category { get => _category; set => SetProperty(ref _category, value); } public ICommand ViewProductDetailsCommand { get; } public ProductsViewModel( INavigationService navigationService, IDialogService dialogService) { _navigationService = navigationService; _dialogService = dialogService; ViewProductDetailsCommand = new AsyncCommand(async (productId, ct) => { // 导航到产品详情页,传递产品ID await _navigationService.NavigateAsync(productId); }); } // 导航生命周期:进入页面时 public async Task OnNavigatedToAsync(object? parameter) { if (parameter is string category) { Category = category; _dialogService.ShowMessage($"显示分类: {category}", "提示"); } // 可以在这里加载数据 await LoadProductsAsync(); } // 导航生命周期:离开页面时 public async Task OnNavigatedFromAsync() { // 清理资源、保存状态等 await Task.CompletedTask; } private async Task LoadProductsAsync() { IsBusy = true; await Task.Delay(500); // 模拟加载 IsBusy = false; } } ``` ### 3. ProductDetailViewModel.cs - 详情页(带结果返回) ```csharp public class ProductDetailViewModel : ViewModelBase, INavigationAware, INavigationResult // 返回 bool(是否购买) { private readonly TaskCompletionSource _resultSource = new(); private int _productId; private string _productName = ""; public int ProductId { get => _productId; set => SetProperty(ref _productId, value); } public string ProductName { get => _productName; set => SetProperty(ref _productName, value); } public ICommand BuyCommand { get; } public ICommand CancelCommand { get; } public ProductDetailViewModel() { BuyCommand = new RelayCommand(() => { // 返回结果:已购买 _resultSource.SetResult(true); }); CancelCommand = new RelayCommand(() => { // 返回结果:取消 _resultSource.SetResult(false); }); } public async Task OnNavigatedToAsync(object? parameter) { if (parameter is int productId) { ProductId = productId; // 加载产品详情 ProductName = $"产品 #{productId}"; } await Task.CompletedTask; } public Task OnNavigatedFromAsync() => Task.CompletedTask; // 实现 INavigationResult public Task GetResultAsync() { return _resultSource.Task; } } ``` ### 4. App.xaml.cs - 注册导航服务 ```csharp protected override void OnStartup(StartupEventArgs e) { var services = new ServiceCollection(); services.AddSharpWpf(); // 自动注册 INavigationService // 注册所有页面 ViewModel services.AddViewModel(); services.AddViewModel(); services.AddViewModel(); services.AddViewModel(); services.AddViewModel(); var provider = services.BuildServiceProvider(); var mainWindow = provider.GetRequiredService(); mainWindow.Show(); } ``` ### 5. MainWindow.xaml - 导航容器 ```xml