准备工作
引入wpf-ui NuGet 包
设置App.xaml文件
<Application
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Light" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
将Window窗口类型更改为FluentWindow
ExtendsContentIntoTitleBar="True"- 添加
ui:TitleBar控件
使用导航
基本
使用导航需要注入3个接口, 分别是INavigationService,INavigationWindow和IPageService, INavigationService wpfui 有提供现成的类 NavigationService,而IPageService和INavigationWindow需要自己实现,不过也不难,官方示例代码写的有,照抄就是.
IPageService实现
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Wpf.Ui;
public class PageService : IPageService
{
private readonly IServiceProvider _serviceProvider;
public PageService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public T? GetPage<T>() where T : class
{
if (!typeof(FrameworkElement).IsSubclassOf(typeof(T)))
{
throw new InvalidOperationException("The page should be a WPF control.");
}
return (T?)_serviceProvider.GetRequiredService(typeof(T));
}
public FrameworkElement? GetPage(Type pageType)
{
if (!typeof(FrameworkElement).IsAssignableFrom(pageType))
{
throw new InvalidOperationException("The page should be a WPF control.");
}
return _serviceProvider.GetService(pageType) as FrameworkElement;
}
}
INavigationWindow实现
using System.Windows.Controls;
using RandomMod.Core.ViewModels;
using Wpf.Ui;
using Wpf.Ui.Controls;
public partial class MainNavigationUserControl : UserControl, INavigationWindow
{
public MainNavigationUserControl(MainNavigationViewModel model, INavigationService navigationService)
{
InitializeComponent();
DataContext = model;
navigationService.SetNavigationControl(RootNavigation);
// 用来在加载完成后显示默认页
Loaded += (_, _) => RootNavigation.Navigate("default");
}
#region INavigationWindow 接口实现
public INavigationView GetNavigation()
{
return RootNavigation;
}
public bool Navigate(Type pageType)
{
return RootNavigation.Navigate(pageType);
}
public void SetServiceProvider(IServiceProvider serviceProvider)
{
RootNavigation.SetServiceProvider(serviceProvider);
}
public void SetPageService(IPageService pageService)
{
RootNavigation.SetPageService(pageService);
}
public void ShowWindow()
{
throw new NotImplementedException();
}
public void CloseWindow()
{
throw new NotImplementedException();
}
INavigationView INavigationWindow.GetNavigation()
{
throw new NotImplementedException();
}
#endregion
}
然后就是在导航中添加Page,不过需要先设置一下RootNavigationView
using System.Collections.ObjectModel;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
using Wpf.Ui;
using Wpf.Ui.Controls;
public partial class MainWindow : Window
{
public MainWindow(IPageService pageService, MainWindowViewModel model)
{
DataContext = model;
InitializeComponent();
// 为NavigationView设置PageService
RootNavigationView.SetPageService(pageService);
}
}
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<object> _navigationItems = [];
public MainWindowViewModel()
{
NavigationItems =
[
new NavigationViewItem()
{
Content = "Home",
Icon = new SymbolIcon { Symbol = SymbolRegular.Home24 },
TargetPageType = typeof(HomePage)
},
new NavigationViewItem()
{
Content = "Counter",
TargetPageType = typeof(CounterPage)
},
];
}
}
然后在 Ioc 容器中添加
var builder = Host.CreateApplicationBuilder();
builder.Services.AddSingleton<INavigationService, NavigationService>();
builder.Services.AddSingleton<INavigationWindow, MainNavigationUserControl>();
builder.Services.AddSingleton<IPageService, PageService>();
大功告成
设置导航初始页面
NavigationPage.xaml
<ui:NavigationView x:Name="RootNavigation"></ui:NavigationView>
NavigationPage.xaml.cs
public partial class NavigationPage : Page
{
public NavigationPage(NavigationPageModel model)
{
InitializeComponent();
DataContext = model;
Loaded += (_, _) => RootNavigation.Navigate(type(MyDashboardClass));
}
}