WPF UI库使用指南

774 阅读1分钟

项目地址

准备工作

引入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

  1. ExtendsContentIntoTitleBar="True"
  2. 添加ui:TitleBar控件

使用导航

基本

使用导航需要注入3个接口, 分别是INavigationService,INavigationWindowIPageService, INavigationService wpfui 有提供现成的类 NavigationService,而IPageServiceINavigationWindow需要自己实现,不过也不难,官方示例代码写的有,照抄就是.

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 : UserControlINavigationWindow
{
    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));
    }
}