描述
当我们安装完 DotNetCore 3.0 版本的 SDK 后,我们就可以创建基于 DotNetCore 的 WPF 项目模板,通过如下 CLI 可以方便快捷的创建并运行我们的项目:
dotnet new wpf -n WpfApp cd WpfApp dotnet restore dotnet run
做过 WPF 开发的朋友都知道,这个项目模板肯定不符合我们的预期,我们希望我们的项目模板能够加入 MVVM 的默认代码段,并且能够和 DotNetCore 紧密合作,这样岂不是更加方便了吗? 所以本文使用 MVVM 的一种实现 MvvmLightStd10 来教大家如何创建一个我们理想的项目模板。
操作
首先,我们基于 DotNetCore 3.0 创建一个原始的 WPF 项目模板,然后引用如下库:
Microsoft.Extensions.DependencyInjection
MvvmLightLibsStd10
可通过执行 cli 命令进行安装
dotnet add package Microsoft.Extensions.DependencyInjection dotnet add package MvvmLightLibsStd10
注:因为我们使用了 DotNetCore,所以我们尽量让我们安装的第三方包是基于 .NET Standard 方式来实现。
然后,尝试修改我们的这个项目,把它改成我们以后期望创建的项目模板的样子。可以参考我的如下修改:
项目结构如下图所示:
其中,src\Models\DataItem.cs 的示例代码如下所示:
using System; using System.Collections.Generic; using System.Text; namespace WpfApp.Models { public class DataItem { public string Title { get; private set; } public DataItem(string title) { Title = title; } } }
src\Models\IDataService.cs 的示例代码如下所示:
using System; using System.Collections.Generic; using System.Text; namespace WpfApp.Models { public interface IDataService { void GetData(Action<DataItem, Exception> callback); } }
src\Models\DataService.cs 的示例代码如下所示:
using System; using System.Collections.Generic; using System.Text; namespace WpfApp.Models { public class DataService : IDataService { public void GetData(Action<DataItem, Exception> callback) { var item = new DataItem("Hello .NET Core!"); callback(item, null); } } }
src\ViewModels\MainViewModel.cs 的示例代码如下所示:
using GalaSoft.MvvmLight; using WpfApp.Models; namespace WpfApp.ViewModels { public class MainViewModel : ViewModelBase { private readonly IDataService _dataService; private string _welcomeTitle; public string WelcomeTitle { get { return _welcomeTitle; } set { Set(ref _welcomeTitle, value); } } public MainViewModel(IDataService dataService) { _dataService = dataService; _dataService.GetData( (item, error) => { if (error != null) { return; } WelcomeTitle = item.Title; }); } } }
src\Views\MainView.xaml 的示例代码如下所示:
<Window x:Class="WpfApp.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="MainWindow" mc:Ignorable="d"> <Grid> <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding WelcomeTitle}" FontSize="40" /> </Grid> </Window>
src\Views\MainView.xaml.cs 的示例代码如下所示:
using System.Windows; using WpfApp.ViewModels; namespace WpfApp.Views { public partial class MainView : Window { public MainView(MainViewModel vm) { InitializeComponent(); this.DataContext = vm; } } }
src\App.xaml 的示例代码如下所示:
<Application x:Class="WpfApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp" />
src\App.xaml.cs 的示例代码如下所示:
using Microsoft.Extensions.DependencyInjection; using System.Windows; using WpfApp.Models; using WpfApp.ViewModels; using WpfApp.Views; namespace WpfApp { public partial class App : Application { public ServiceProvider ServiceProvider { get; private set; } protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var serviceCollection = new ServiceCollection(); ConfigureServices(serviceCollection); ServiceProvider = serviceCollection.BuildServiceProvider(); var mainWindow = ServiceProvider.GetRequiredService<MainView>(); mainWindow.Show(); } private void ConfigureServices(ServiceCollection services) { services.AddTransient<MainView>(); services.AddTransient<MainViewModel>(); services.AddScoped<IDataService, DataService>(); } } }
修改完毕后尝试编译运行我们的项目,确保可以正常编译运行。
之后,在我们的项目根目录 src 下新建一个 .template.config 文件夹,然后在里面新建一个 template.json 文件,进行如下示例配置: